Aby uprościć odpowiedź, Vector3
jest to zwyczaj struct
dostarczony przez UnityEngine
przestrzeń nazw. Kiedy tworzymy niestandardowe class
lub struct
typy, 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 == _positionB
ma sens, jak możemy bezpośrednio sprawdzić Vector3.x
, Vector3.y
i Vector3.z
wartości. _rect_tfm.position >= _positionB
nie ma większego sensu, ponieważ a Vector3
jest reprezentowane przez trzy oddzielne wartości.
Moglibyśmy przeciążyć Vector3
klasę, aby zawierała odpowiednie operatory w teorii , ale wydaje się to dość skomplikowane. Zamiast tego łatwiej byłoby po prostu przedłużyć o Vector3
klasę 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.Lerp
metody może być znacznie łatwiejsze ; jeśli tak, czytaj dalej poniżej.
Dodanie metod rozszerzenia do Vector3
Jak wcześniej wspomniano, zastosowanie <=
lub >=
do Vector3
jest często nielogiczne. Jeśli chodzi o ruch, prawdopodobnie chcesz przeczytać więcej na temat tej Vector3.Lerp
metody. To powiedziawszy, możesz chcieć zastosować <=
=>
arytmetykę z innych powodów, więc dam ci łatwą alternatywę.
Zamiast stosowania logiki Vector3 <= Vector3
lub Vector3 >= Vector3
proponuję rozszerzenie Vector3
klasy o metody dla isGreaterOrEqual(Vector3 other)
i isLesserOrEqual(Vector3)
. Możemy dodać metody rozszerzenia do a struct
lub class
deklarując je w static
klasie, która nie dziedziczy. Uwzględniamy również cel class
lub struct
jako pierwszy parametr za pomocą this
sł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
, y
i 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 Vector3
klasy, local
będzie reprezentować Vector3
instancję, 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 Vector3
typów.
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Przeprowadzka Vector3
zVector3.Lerp
Nazywając ten Vector3.Lerp
sposób pozwala nam określić dokładną pozycję między dwoma Vector3
wartoś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ę.Vector3
Vector3.Lerp
Vector3
Rozwiązując problem, proponuję użyć, Vector3.Lerp
aby przejść do targetPosition
. Po wywołaniu Move
metody w każdym z nich Update
możemy sprawdzić, czy osiągnęliśmy wspomniany cel; Lerp.Vector3
będzie nie przeregulowanie, więc transform.position == targetPosition
staje się wiarygodne. Możemy teraz sprawdzić pozycję i odpowiednio zmienić ruch targetPosition
na leftPosition
lub rightPosition
odwró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 .
Bools
takich jak_atPosA
i_atPosB
. Nieuchronnie popełnisz błąd, utrzymując je obie w synchronizacji, co doprowadzi do błędów. Lepiej zrobićenum
zawierający wszystkie pozycje (A, B, być może inne w przyszłości) i używając tego