Para simplificar a resposta, Vector3é um costume structfornecido pelo UnityEngineespaço para nome. Quando criamos tipos classou personalizados struct, também devemos definir seus operadores . Como tal, não há lógica padrão para o >=operador. Como apontado por Evgeny Vasilyev , _rect_tfm.position == _positionBfaz sentido, como podemos verificar diretamente as Vector3.x, Vector3.ye Vector3.zvalores. _rect_tfm.position >= _positionBnão faz tanto sentido, devido ao fato de que a Vector3é representado por três valores separados.
Poderíamos sobrecarregar a Vector3classe para conter os operadores adequados na teoria , mas isso parece bastante complicado. Em vez disso, seria mais fácil simplesmente estender a Vector3classe com um método adequado . Dito isto, parece que você pretende usar essa lógica para o movimento. Como tal, você pode achar muito mais fácil usar o Vector3.Lerpmétodo; Nesse caso, leia mais abaixo.
Adicionando métodos de extensão a Vector3
Como mencionado anteriormente, aplicar <=ou >=a um Vector3é frequentemente ilógico. Para movimento, você provavelmente deseja ler mais sobre o Vector3.Lerpmétodo. Dito isto, você pode aplicar a <= =>aritmética por outros motivos, portanto, darei uma alternativa fácil.
Em vez de aplicar a lógica de Vector3 <= Vector3ou Vector3 >= Vector3, proponho estender a Vector3classe para incluir métodos para isGreaterOrEqual(Vector3 other)e isLesserOrEqual(Vector3). Podemos adicionar métodos de extensão a structou classdeclarando-os em uma staticclasse que não herda. Também incluímos o destino classou structcomo o primeiro parâmetro, usando a thispalavra - chave Observe que, no meu exemplo, suponho que você queira garantir que todos os três valores principais ( x, ye z) sejam todos maiores ou iguais, ou menores ou iguais, respectivamente. Você pode fornecer sua própria lógica, aqui, conforme necessário.
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 tentamos chamar esses métodos da Vector3classe, localrepresentamos a Vector3instância da qual estamos chamando o método. Você observará que os métodos são static; métodos de extensão devem ser static, mas você ainda precisa chamá-los de uma instância. Dado os métodos de extensão acima, agora você pode aplicá-los diretamente aos seus Vector3tipos.
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Movendo-se Vector3comVector3.Lerp
Chamar o Vector3.Lerpmétodo nos permite determinar a posição exata entre dois Vector3valores em um determinado momento. Um benefício adicional desse método é que o Vector3não ultrapassará seu objetivo . Vector3.Lerpleva três parâmetros; a posição inicial, a posição final e a posição atual representada como um valor entre 0 e 1. Ela gera a posição resultante como a Vector3, a qual podemos definir diretamente como a posição atual.
Resolvendo o seu problema, proponho usar Vector3.Lerpa mudança para a targetPosition. Depois de chamar o Movemétodo em cada um Update, podemos verificar se atingimos o objetivo; Lerp.Vector3vai não ultrapassagem, por isso transform.position == targetPositiontorna-se confiável. Agora podemos verificar a posição e alterar targetPositionpara leftPositionou rightPositionpara reverter o movimento, de acordo.
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);
}
Você pode ver isso demonstrado na animação a seguir. Traduzo o cubo azul com Vector3.LerpUnclamped, o que nos dá um resultado semelhante à tradução desmarcada simples. Eu traduzo o cubo vermelho usando Vector3.Lerp. Deixado desmarcado, o cubo azul se move para o esquecimento; enquanto o cubo vermelho para exatamente onde eu pretendo. Você pode ler mais sobre esse tipo de movimento na documentação Estouro de pilha .

Boolscomo_atPosAe_atPosB. Inevitavelmente, você cometerá um erro ao manter os dois em sincronia, e isso causará bugs. É melhor criar umenumcontendo todas as posições (A, B, talvez outras no futuro), e usando isso