Aby uprościć odpowiedź, Vector3jest to zwyczaj structdostarczony przez UnityEngineprzestrzeń nazw. Kiedy tworzymy niestandardowe classlub structtypy, musimy również zdefiniować ich operatorów . W związku z tym >=operator nie ma domyślnej logiki . Jak podkreślił Evgeny Wasiliew , _rect_tfm.position == _positionBma sens, jak możemy bezpośrednio sprawdzić Vector3.x, Vector3.yi Vector3.zwartości. _rect_tfm.position >= _positionBnie ma większego sensu, ponieważ a Vector3jest reprezentowane przez trzy oddzielne wartości.
Moglibyśmy przeciążyć Vector3klasę, aby zawierała odpowiednie operatory w teorii , ale wydaje się to dość skomplikowane. Zamiast tego łatwiej byłoby po prostu przedłużyć o Vector3klasę z odpowiednim sposobem . Biorąc to pod uwagę, wydaje się, że zamierzasz użyć tej logiki do poruszania się. W związku z tym korzystanie z tej Vector3.Lerpmetody może być znacznie łatwiejsze ; jeśli tak, czytaj dalej poniżej.
Dodanie metod rozszerzenia do Vector3
Jak wcześniej wspomniano, zastosowanie <=lub >=do Vector3jest często nielogiczne. Jeśli chodzi o ruch, prawdopodobnie chcesz przeczytać więcej na temat tej Vector3.Lerpmetody. To powiedziawszy, możesz chcieć zastosować <= =>arytmetykę z innych powodów, więc dam ci łatwą alternatywę.
Zamiast stosowania logiki Vector3 <= Vector3lub Vector3 >= Vector3proponuję rozszerzenie Vector3klasy o metody dla isGreaterOrEqual(Vector3 other)i isLesserOrEqual(Vector3). Możemy dodać metody rozszerzenia do a structlub classdeklarując je w staticklasie, która nie dziedziczy. Uwzględniamy również cel classlub structjako pierwszy parametr za pomocą thissłowa kluczowego. Należy zauważyć, że w moim przykładzie zakładamy, że masz na myśli, aby upewnić się, że wszystkie trzy główne wartości ( x, yi z) są wszystkie większe lub równe lub mniejsze lub równe, odpowiednio. Tutaj możesz podać własną logikę, zgodnie z wymaganiami.
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;
}
}
}
Kiedy spróbujemy wywołać te metody z Vector3klasy, localbędzie reprezentować Vector3instancję, z której wywołujemy metodę. Zauważysz, że metody są static; metody rozszerzenia muszą być static, ale nadal musisz wywoływać je z instancji. Biorąc pod uwagę powyższe metody rozszerzenia, możesz teraz zastosować je bezpośrednio do swoich Vector3typów.
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Przeprowadzka Vector3zVector3.Lerp
Nazywając ten Vector3.Lerpsposób pozwala nam określić dokładną pozycję między dwoma Vector3wartościami w danym czasie. Dodatkową zaletą tej metody jest to, że nie wykroczy swój cel . przyjmuje trzy parametry; pozycja początkowa, końcowa i bieżąca pozycja reprezentowane jako wartość od 0 do 1. Wyprowadza wynikową pozycję jako a , którą możemy bezpośrednio ustawić jako bieżącą pozycję.Vector3Vector3.LerpVector3
Rozwiązując problem, proponuję użyć, Vector3.Lerpaby przejść do targetPosition. Po wywołaniu Movemetody w każdym z nich Updatemożemy sprawdzić, czy osiągnęliśmy wspomniany cel; Lerp.Vector3będzie nie przeregulowanie, więc transform.position == targetPositionstaje się wiarygodne. Możemy teraz sprawdzić pozycję i odpowiednio zmienić ruch targetPositionna leftPositionlub rightPositionodwrócić.
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);
}
Można to zobaczyć na poniższej animacji. Tłumaczę niebieski sześcian za pomocą Vector3.LerpUnclamped, co daje nam podobny wynik do prostego niesprawdzonego tłumaczenia. Tłumaczę czerwony sześcian za pomocą Vector3.Lerp. Pozostawiony bez zaznaczenia, niebieski sześcian rusza w zapomnienie; podczas gdy czerwony sześcian zatrzymuje się dokładnie tam, gdzie zamierzam. Możesz przeczytać więcej o tym rodzaju ruchu w dokumentacji przepełnienia stosu .

Boolstakich jak_atPosAi_atPosB. Nieuchronnie popełnisz błąd, utrzymując je obie w synchronizacji, co doprowadzi do błędów. Lepiej zrobićenumzawierający wszystkie pozycje (A, B, być może inne w przyszłości) i używając tego