Per semplificare la risposta, Vector3è un'abitudine structfornita dallo UnityEnginespazio dei nomi. Quando creiamo personalizzazioni classo structtipi, dobbiamo anche definire i suoi operatori . Pertanto, non esiste una logica predefinita per l' >=operatore. Come sottolineato da Evgeny Vasilyev , _rect_tfm.position == _positionBha senso, come si può controllare direttamente i Vector3.x, Vector3.ye Vector3.zvalori. _rect_tfm.position >= _positionBnon ha molto senso, a causa del fatto che a Vector3è rappresentato da tre valori separati.
Potremmo sovraccaricare la Vector3classe per contenere in teoria gli operatori adatti , ma sembra piuttosto complicato. Invece, sarebbe più semplice estendere semplicemente la Vector3classe 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.Lerpmetodo; 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.Lerpmetodo. Detto questo, potresti voler applicare l' <= =>aritmetica per altri motivi, quindi ti darò una facile alternativa.
Invece di applicare la logica di Vector3 <= Vector3o Vector3 >= Vector3, propongo di estendere la Vector3classe per includere metodi per isGreaterOrEqual(Vector3 other)e isLesserOrEqual(Vector3). È possibile aggiungere metodi di estensione a structo classdichiarandoli in una staticclasse che non eredita. Includiamo anche il target classo structcome primo parametro, usando la thisparola chiave. Si noti che nel mio esempio, suppongo che si intende far sì che tutti i tre valori principali ( x, ye 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 Vector3classe, localrappresenterà l' Vector3istanza 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 Vector3tipi.
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Muoversi Vector3conVector3.Lerp
La chiamata del Vector3.Lerpmetodo ci consente di determinare la posizione esatta tra due Vector3valori in un determinato momento. Un ulteriore vantaggio di questo metodo è che il Vector3non supererà il suo obiettivo . Vector3.Lerpaccetta 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.Lerpper passare a targetPosition. Dopo aver chiamato il Movemetodo 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 == targetPositiontargetPositionleftPositionrightPosition
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 .

Boolslike_atPosAe_atPosB. Inevitabilmente, commetterai un errore mantenendo entrambi sincronizzati e porterai a bug. È meglio fare unenumcontenente tutte le posizioni (A, B, forse altre in futuro), e usarlo