Pour simplifier la réponse, Vector3
une coutume est struct
fournie par l' UnityEngine
espace de noms. Lorsque nous créons des types class
ou des struct
types 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 == _positionB
est logique, comme nous pouvons vérifier directement les Vector3.x
, Vector3.y
et les Vector3.z
valeurs. _rect_tfm.position >= _positionB
n'a pas autant de sens, car a Vector3
est représenté par trois valeurs distinctes.
Nous pourrions surcharger la Vector3
classe 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 Vector3
classe 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.Lerp
méthode; si oui, lisez plus loin ci-dessous.
Ajout de méthodes d'extension à Vector3
Comme mentionné précédemment, l'application <=
ou >=
à un Vector3
est souvent illogique. Pour le mouvement, vous voudrez probablement lire plus loin pour la Vector3.Lerp
mé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 <= Vector3
ou Vector3 >= Vector3
, je propose d'étendre la Vector3
classe pour inclure les méthodes de isGreaterOrEqual(Vector3 other)
et isLesserOrEqual(Vector3)
. Nous pouvons ajouter des méthodes d'extension à a struct
ou class
en les déclarant dans une static
classe qui n'hérite pas. Nous incluons également la cible class
ou struct
comme premier paramètre, en utilisant le this
mot - clé. Notez que dans mon exemple, je suppose que vous voulez vous assurer que les trois valeurs principales ( x
, y
et 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 Vector3
classe, local
représentera l' Vector3
instance à 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 Vector3
types.
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Se déplacer Vector3
avecVector3.Lerp
L'appel de la Vector3.Lerp
méthode nous permet de déterminer la position exacte entre deux Vector3
valeurs à un instant donné. Un autre avantage de cette méthode est que la Vector3
ne sera pas dépasser son objectif . Vector3.Lerp
prend 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.Lerp
pour passer à a targetPosition
. Après avoir appelé la Move
méthode dans chacun Update
, nous pouvons vérifier si nous avons atteint ladite cible; Lerp.Vector3
sera pas remise des gaz, donc transform.position == targetPosition
devient fiable. Nous pouvons maintenant vérifier la position et modifier le targetPosition
en leftPosition
ou rightPosition
pour 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 .
Bools
comme_atPosA
et_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 unenum
contenant toutes les positions (A, B, peut-être d'autres à l'avenir), et d'utiliser cela