Um die Antwort zu vereinfachen, Vector3wird eine benutzerdefinierte Funktion structvom UnityEngineNamespace bereitgestellt . Wenn wir benutzerdefinierte classoder structTypen erstellen , müssen wir auch deren Operatoren definieren . Daher gibt es keine Standardlogik für den >=Bediener. Wie durch wies darauf hin , Evgeny Vasilyev , _rect_tfm.position == _positionBmacht Sinn, da wir direkt die überprüfen können Vector3.x, Vector3.yund Vector3.zWerte. _rect_tfm.position >= _positionBmacht nicht so viel Sinn, da a Vector3durch drei separate Werte dargestellt wird.
Wir könnten die Vector3Klasse überladen , um theoretisch die geeigneten Operatoren zu enthalten , aber das scheint ziemlich kompliziert zu sein. Stattdessen wäre es einfacher , die Vector3Klasse einfach mit einer geeigneten Methode zu erweitern . Davon abgesehen scheint es, dass Sie beabsichtigen, diese Logik für die Bewegung zu verwenden. Daher ist es möglicherweise viel einfacher, die Vector3.LerpMethode zu verwenden. Wenn ja, lesen Sie weiter unten.
Hinzufügen von Erweiterungsmethoden zu Vector3
Wie bereits erwähnt, die Anwendung <=oder >=auf ein Vector3oft unlogisch. Für die Bewegung möchten Sie wahrscheinlich weiter für die Vector3.LerpMethode lesen . Das heißt, Sie möchten die <= =>Arithmetik vielleicht aus anderen Gründen anwenden , also werde ich Ihnen eine einfache Alternative geben.
Anstatt die Logik von Vector3 <= Vector3oder anzuwenden Vector3 >= Vector3, schlage ich vor, die Vector3Klasse um Methoden für isGreaterOrEqual(Vector3 other)und zu erweitern isLesserOrEqual(Vector3). Wir können einem oder Erweiterungsmethoden hinzufügen, indem wir sie in einer Klasse deklarieren , die nicht erbt. Wir geben auch das Ziel oder als ersten Parameter mit dem Schlüsselwort an. Beachten Sie, dass ich in meinem Beispiel davon ausgehe, dass Sie sicherstellen möchten, dass alle drei Hauptwerte ( , und ) alle größer oder gleich oder kleiner oder gleich sind. Hier können Sie nach Bedarf Ihre eigene Logik bereitstellen.structclassstaticclassstructthisxyz
public static class ExtendingVector3
{
public static bool IsGreaterOrEqual(this Vector3 local, Vector3 other)
{
if(local.x >= other.x && local.y >= other.y && local.z >= other.z)
{
return true;
}
else
{
return false;
}
}
public static bool IsLesserOrEqual(this Vector3 local, Vector3 other)
{
if(local.x <= other.x && local.y <= other.y && local.z <= other.z)
{
return true;
}
else
{
return false;
}
}
}
Wenn wir versuchen, diese Methoden aus der Vector3Klasse aufzurufen , localwird die Vector3Instanz dargestellt, von der aus wir die Methode aufrufen. Sie werden feststellen, dass die Methoden sind static; Erweiterungsmethoden müssen vorhanden sein static, Sie müssen sie jedoch weiterhin von einer Instanz aus aufrufen. Mit den oben genannten Erweiterungsmethoden können Sie sie jetzt direkt auf Ihre Vector3Typen anwenden .
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Umzug Vector3mitVector3.Lerp
Durch Aufrufen der Vector3.LerpMethode können wir die genaue Position zwischen zwei Vector3Werten zu einem bestimmten Zeitpunkt bestimmen . Ein zusätzlicher Vorteil dieser Methode ist, dass das Vector3Ziel nicht überschritten wird . Vector3.Lerpnimmt drei Parameter; Die Startposition, die Endposition und die aktuelle Position werden als Wert zwischen 0 und 1 dargestellt. Sie gibt die resultierende Position als a aus Vector3, die wir direkt als aktuelle Position festlegen können.
Um Ihr Problem zu lösen, schlage ich vor Vector3.Lerp, zu einem zu wechseln targetPosition. Nach dem Aufruf der MoveMethode in jedem Updatekönnen wir überprüfen, ob wir das Ziel erreicht haben; Lerp.Vector3wird nicht überschießen, transform.position == targetPositionwird also zuverlässig. Wir können nun die Position überprüfen und ändern die targetPositionzu leftPositionoder rightPositiondie Bewegung umgekehrt, entsprechend.
public Vector3 leftPosition, rightPosition;
public float speed;
public Vector3 targetPosition;
private void Awake()
{
targetPosition = rightPosition;
}
private void Update()
{
Move();
if(transform.position == targetPosition)
{
// We have arrived at our intended position. Move towards the other position.
if(targetPosition == rightPosition)
{
// We were moving to the right; time to move to the left.
targetPosition = leftPosition;
}
else
{
// We were moving to the left; time to move to the right.
targetPosition = rightPosition;
}
}
}
private void Move()
{
// First, we need to find out the total distance we intend to move.
float distance = Vector3.Distance(transform.position, targetPosition);
// Next, we need to find out how far we intend to move.
float movement = speed * Time.deltaTime;
// We find the increment by simply dividing movement by distance.
// This will give us a decimal value. If the decimal is greater than
// 1, we are moving more than the remaining distance. Lerp
// caps this number at 1, which in turn, returns the end position.
float increment = movement / distance;
// Lerp gives us the absolute position, so we pass it straight into our transform.
transform.position = Vector3.Lerp(transform.position, targetPosition, increment);
}
Sie können dies in der folgenden Animation demonstrieren. Ich übersetze den blauen Würfel mit Vector3.LerpUnclamped, was uns ein ähnliches Ergebnis wie eine einfache ungeprüfte Übersetzung gibt. Ich übersetze den roten Würfel mit Vector3.Lerp. Wenn das Kontrollkästchen nicht aktiviert ist, gerät der blaue Würfel in Vergessenheit. während der rote Würfel genau dort anhält, wo ich es beabsichtige. Weitere Informationen zu dieser Art von Bewegung finden Sie in der Dokumentation zum Stapelüberlauf .

Boolswie_atPosAund zu verwenden_atPosB. Es ist unvermeidlich, dass Sie einen Fehler machen, wenn Sie beide synchron halten, und dies führt zu Fehlern. Es ist besserenum, alle Positionen (A, B, vielleicht andere in der Zukunft) zu enthalten und diese zu verwenden