Para simplificar a resposta, Vector3
é um costume struct
fornecido pelo UnityEngine
espaço para nome. Quando criamos tipos class
ou 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 == _positionB
faz sentido, como podemos verificar diretamente as Vector3.x
, Vector3.y
e Vector3.z
valores. _rect_tfm.position >= _positionB
não faz tanto sentido, devido ao fato de que a Vector3
é representado por três valores separados.
Poderíamos sobrecarregar a Vector3
classe para conter os operadores adequados na teoria , mas isso parece bastante complicado. Em vez disso, seria mais fácil simplesmente estender a Vector3
classe 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.Lerp
mé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.Lerp
mé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 <= Vector3
ou Vector3 >= Vector3
, proponho estender a Vector3
classe para incluir métodos para isGreaterOrEqual(Vector3 other)
e isLesserOrEqual(Vector3)
. Podemos adicionar métodos de extensão a struct
ou class
declarando-os em uma static
classe que não herda. Também incluímos o destino class
ou struct
como o primeiro parâmetro, usando a this
palavra - chave Observe que, no meu exemplo, suponho que você queira garantir que todos os três valores principais ( x
, y
e 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 Vector3
classe, local
representamos a Vector3
instâ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 Vector3
tipos.
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Movendo-se Vector3
comVector3.Lerp
Chamar o Vector3.Lerp
método nos permite determinar a posição exata entre dois Vector3
valores em um determinado momento. Um benefício adicional desse método é que o Vector3
não ultrapassará seu objetivo . Vector3.Lerp
leva 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.Lerp
a mudança para a targetPosition
. Depois de chamar o Move
método em cada um Update
, podemos verificar se atingimos o objetivo; Lerp.Vector3
vai não ultrapassagem, por isso transform.position == targetPosition
torna-se confiável. Agora podemos verificar a posição e alterar targetPosition
para leftPosition
ou rightPosition
para 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 .
Bools
como_atPosA
e_atPosB
. Inevitavelmente, você cometerá um erro ao manter os dois em sincronia, e isso causará bugs. É melhor criar umenum
contendo todas as posições (A, B, talvez outras no futuro), e usando isso