Per semplificare la risposta, Vector3
è un'abitudine struct
fornita dallo UnityEngine
spazio dei nomi. Quando creiamo personalizzazioni class
o struct
tipi, dobbiamo anche definire i suoi operatori . Pertanto, non esiste una logica predefinita per l' >=
operatore. Come sottolineato da Evgeny Vasilyev , _rect_tfm.position == _positionB
ha senso, come si può controllare direttamente i Vector3.x
, Vector3.y
e Vector3.z
valori. _rect_tfm.position >= _positionB
non ha molto senso, a causa del fatto che a Vector3
è rappresentato da tre valori separati.
Potremmo sovraccaricare la Vector3
classe per contenere in teoria gli operatori adatti , ma sembra piuttosto complicato. Invece, sarebbe più semplice estendere semplicemente la Vector3
classe con un metodo adatto . Detto questo, sembra che tu abbia intenzione di usare questa logica per il movimento. Pertanto, potrebbe essere molto più semplice utilizzare il Vector3.Lerp
metodo; in tal caso, leggi di seguito.
Aggiunta di metodi di estensione a Vector3
Come accennato in precedenza, l'applicazione <=
o >=
a Vector3
è spesso illogica. Per il movimento, probabilmente vorrai leggere più avanti per il Vector3.Lerp
metodo. Detto questo, potresti voler applicare l' <=
=>
aritmetica per altri motivi, quindi ti darò una facile alternativa.
Invece di applicare la logica di Vector3 <= Vector3
o Vector3 >= Vector3
, propongo di estendere la Vector3
classe per includere metodi per isGreaterOrEqual(Vector3 other)
e isLesserOrEqual(Vector3)
. È possibile aggiungere metodi di estensione a struct
o class
dichiarandoli in una static
classe che non eredita. Includiamo anche il target class
o struct
come primo parametro, usando la this
parola chiave. Si noti che nel mio esempio, suppongo che si intende far sì che tutti i tre valori principali ( x
, y
e z
) sono tutte maggiore o uguale, o minore o uguale, rispettivamente. Puoi fornire la tua logica, qui, come richiesto.
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;
}
}
}
Quando proviamo a chiamare questi metodi dalla Vector3
classe, local
rappresenterà l' Vector3
istanza da cui stiamo chiamando il metodo. Noterai che i metodi sono static
; i metodi di estensione devono essere static
, ma è comunque necessario chiamarli da un'istanza. Dati i metodi di estensione di cui sopra, ora puoi applicarli direttamente ai tuoi Vector3
tipi.
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Muoversi Vector3
conVector3.Lerp
La chiamata del Vector3.Lerp
metodo ci consente di determinare la posizione esatta tra due Vector3
valori in un determinato momento. Un ulteriore vantaggio di questo metodo è che il Vector3
non supererà il suo obiettivo . Vector3.Lerp
accetta tre parametri; la posizione iniziale, la posizione finale e la posizione corrente rappresentata come un valore compreso tra 0 e 1. Emette la posizione risultante come a Vector3
, che possiamo impostare direttamente come posizione corrente.
Risolvendo il tuo problema, propongo di utilizzare Vector3.Lerp
per passare a targetPosition
. Dopo aver chiamato il Move
metodo in ciascuno Update
, possiamo verificare se abbiamo raggiunto tale obiettivo; nonLerp.Vector3
supererà , quindi diventa affidabile. Ora possiamo controllare la posizione e cambiare in o per invertire il movimento, di conseguenza.transform.position == targetPosition
targetPosition
leftPosition
rightPosition
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);
}
Puoi vederlo dimostrato nella seguente animazione. Traduco il cubo blu con Vector3.LerpUnclamped
, che ci dà un risultato simile alla semplice traduzione non selezionata. Traduco usando il cubo rosso Vector3.Lerp
. Lasciato deselezionato, il cubo blu si sposta nell'oblio; mentre il cubo rosso si ferma esattamente dove intendo. Puoi leggere ulteriori informazioni su questo tipo di movimento nella documentazione Stack Overflow .
Bools
like_atPosA
e_atPosB
. Inevitabilmente, commetterai un errore mantenendo entrambi sincronizzati e porterai a bug. È meglio fare unenum
contenente tutte le posizioni (A, B, forse altre in futuro), e usarlo