Um die Antwort zu vereinfachen, Vector3
wird eine benutzerdefinierte Funktion struct
vom UnityEngine
Namespace bereitgestellt . Wenn wir benutzerdefinierte class
oder struct
Typen 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 == _positionB
macht Sinn, da wir direkt die überprüfen können Vector3.x
, Vector3.y
und Vector3.z
Werte. _rect_tfm.position >= _positionB
macht nicht so viel Sinn, da a Vector3
durch drei separate Werte dargestellt wird.
Wir könnten die Vector3
Klasse überladen , um theoretisch die geeigneten Operatoren zu enthalten , aber das scheint ziemlich kompliziert zu sein. Stattdessen wäre es einfacher , die Vector3
Klasse 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.Lerp
Methode zu verwenden. Wenn ja, lesen Sie weiter unten.
Hinzufügen von Erweiterungsmethoden zu Vector3
Wie bereits erwähnt, die Anwendung <=
oder >=
auf ein Vector3
oft unlogisch. Für die Bewegung möchten Sie wahrscheinlich weiter für die Vector3.Lerp
Methode 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 <= Vector3
oder anzuwenden Vector3 >= Vector3
, schlage ich vor, die Vector3
Klasse 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.struct
class
static
class
struct
this
x
y
z
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 Vector3
Klasse aufzurufen , local
wird die Vector3
Instanz 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 Vector3
Typen anwenden .
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Umzug Vector3
mitVector3.Lerp
Durch Aufrufen der Vector3.Lerp
Methode können wir die genaue Position zwischen zwei Vector3
Werten zu einem bestimmten Zeitpunkt bestimmen . Ein zusätzlicher Vorteil dieser Methode ist, dass das Vector3
Ziel nicht überschritten wird . Vector3.Lerp
nimmt 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 Move
Methode in jedem Update
können wir überprüfen, ob wir das Ziel erreicht haben; Lerp.Vector3
wird nicht überschießen, transform.position == targetPosition
wird also zuverlässig. Wir können nun die Position überprüfen und ändern die targetPosition
zu leftPosition
oder rightPosition
die 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 .
Bools
wie_atPosA
und 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