Pour simplifier la réponse, Vector3une coutume est structfournie par l' UnityEngineespace de noms. Lorsque nous créons des types classou des structtypes personnalisés , nous devons également définir ses opérateurs . En tant que tel, il n'y a pas de logique par défaut pour l' >=opérateur. Comme l' a souligné Evgeny Vassiliev , _rect_tfm.position == _positionBest logique, comme nous pouvons vérifier directement les Vector3.x, Vector3.yet les Vector3.zvaleurs. _rect_tfm.position >= _positionBn'a pas autant de sens, car a Vector3est représenté par trois valeurs distinctes.
Nous pourrions surcharger la Vector3classe pour contenir les opérateurs appropriés en théorie , mais cela semble plutôt compliqué. Au lieu de cela, il serait plus facile d' étendre simplement la Vector3classe avec une méthode appropriée . Cela étant dit, il semble que vous ayez l'intention d'utiliser cette logique pour le mouvement. En tant que tel, vous pourriez trouver beaucoup plus facile d'utiliser la Vector3.Lerpméthode; si oui, lisez plus loin ci-dessous.
Ajout de méthodes d'extension à Vector3
Comme mentionné précédemment, l'application <=ou >=à un Vector3est souvent illogique. Pour le mouvement, vous voudrez probablement lire plus loin pour la Vector3.Lerpméthode. Cela dit, vous voudrez peut-être appliquer l' <= =>arithmétique pour d'autres raisons, je vais donc vous donner une alternative facile.
Au lieu d'appliquer la logique de Vector3 <= Vector3ou Vector3 >= Vector3, je propose d'étendre la Vector3classe pour inclure les méthodes de isGreaterOrEqual(Vector3 other)et isLesserOrEqual(Vector3). Nous pouvons ajouter des méthodes d'extension à a structou classen les déclarant dans une staticclasse qui n'hérite pas. Nous incluons également la cible classou structcomme premier paramètre, en utilisant le thismot - clé. Notez que dans mon exemple, je suppose que vous voulez vous assurer que les trois valeurs principales ( x, yet z) sont toutes respectivement supérieures ou égales, ou inférieures ou égales. Vous pouvez fournir votre propre logique, ici, selon vos besoins.
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;
}
}
}
Lorsque nous tentons d'appeler ces méthodes à partir de la Vector3classe, localreprésentera l' Vector3instance à partir de laquelle nous appelons la méthode. Vous noterez que les méthodes sont static; les méthodes d'extension doivent l' être static, mais vous devez toujours les appeler à partir d'une instance. Compte tenu des méthodes d'extension ci-dessus, vous pouvez désormais les appliquer directement à vos Vector3types.
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Se déplacer Vector3avecVector3.Lerp
L'appel de la Vector3.Lerpméthode nous permet de déterminer la position exacte entre deux Vector3valeurs à un instant donné. Un autre avantage de cette méthode est que la Vector3ne sera pas dépasser son objectif . Vector3.Lerpprend trois paramètres; la position de départ, la position de fin et la position actuelle représentées comme une valeur comprise entre 0 et 1. Il affiche la position résultante sous la forme a Vector3, que nous pouvons définir directement comme position actuelle.
Pour résoudre votre problème, je propose d'utiliser Vector3.Lerppour passer à a targetPosition. Après avoir appelé la Moveméthode dans chacun Update, nous pouvons vérifier si nous avons atteint ladite cible; Lerp.Vector3sera pas remise des gaz, donc transform.position == targetPositiondevient fiable. Nous pouvons maintenant vérifier la position et modifier le targetPositionen leftPositionou rightPositionpour inverser le mouvement en conséquence.
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);
}
Vous pouvez le voir dans l'animation suivante. Je traduis le cube bleu avec Vector3.LerpUnclamped, ce qui nous donne un résultat similaire à une simple traduction non contrôlée. Je traduis le cube rouge en utilisant Vector3.Lerp. Sans coche, le cube bleu s'éloigne dans l'oubli; tandis que le cube rouge s'arrête exactement là où je le souhaite. Vous pouvez en savoir plus sur ce type de mouvement dans la documentation Stack Overflow .

Boolscomme_atPosAet_atPosB. Inévitablement, vous ferez une erreur en les synchronisant tous les deux, et cela entraînera des bugs. Il est préférable de créer unenumcontenant toutes les positions (A, B, peut-être d'autres à l'avenir), et d'utiliser cela