Чтобы упростить ответ, Vector3
это обычай, struct
предоставляемый UnityEngine
пространством имен. Когда мы создаем custom class
или struct
типы, мы также должны определить его операторы . Таким образом, для >=
оператора нет логики по умолчанию . Как отметил Евгений Васильев , _rect_tfm.position == _positionB
имеет смысл, так как мы можем непосредственно проверить Vector3.x
, Vector3.y
и Vector3.z
значение. _rect_tfm.position >= _positionB
не имеет особого смысла из-за того, что a Vector3
представлено тремя отдельными значениями.
Мы можем перегрузить Vector3
класс, чтобы он содержал подходящие операторы в теории , но это кажется довольно сложным. Вместо этого, было бы проще просто расширить на Vector3
класс с подходящим способом . При этом, похоже, что вы собираетесь использовать эту логику для движения. Таким образом, вам может оказаться гораздо проще использовать Vector3.Lerp
метод; если это так, читайте дальше ниже.
Добавление методов расширения к Vector3
Как упоминалось ранее, применение <=
или >=
к Vector3
часто нелогично. Что касается движения, вы, вероятно, хотите читать дальше для Vector3.Lerp
метода. Тем не менее, вы можете захотеть применить <=
=>
арифметику по другим причинам, поэтому я дам вам легкую альтернативу.
Вместо применения логики Vector3 <= Vector3
или Vector3 >= Vector3
, я предлагаю расширить Vector3
класс, чтобы включить методы для isGreaterOrEqual(Vector3 other)
и isLesserOrEqual(Vector3)
. Мы можем добавить методы расширения к struct
или class
, объявив их в static
классе, который не наследует. Мы также включаем цель class
или struct
в качестве первого параметра, используя this
ключевое слово. Обратите внимание, что в моем примере я предполагаю, что вы хотите убедиться, что все три основных значения ( x
, y
и z
) все больше или равны или меньше или равны соответственно. Вы можете предоставить свою собственную логику здесь, как вам требуется.
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;
}
}
}
Когда мы попытаемся вызвать эти методы из Vector3
класса, local
мы представим Vector3
экземпляр, из которого мы вызываем метод. Вы заметите, что методы есть static
; методы расширения должны быть static
, но вы все равно должны вызывать их из экземпляра. Учитывая вышеописанные методы расширения, теперь вы можете применять их непосредственно к вашим Vector3
типам.
Vector3 left;
Vector3 right;
// Is left >= right?
bool isGreaterOrEqual = left.IsGreaterOrEqual(right);
// Is left <= right?
bool isLesserOrEqual = left.IsLesserOrEqual(right);
Переезд Vector3
сVector3.Lerp
Вызов на Vector3.Lerp
метод позволяет определить точное положение между двумя Vector3
значениями в данный момент времени. Дополнительным преимуществом этого метода является то, что Vector3
он не будет превышать свою цель . Vector3.Lerp
принимает три параметра; начальная позиция, конечная позиция и текущая позиция, представленные в виде значений от 0 до 1. Он выводит результирующую позицию в виде a Vector3
, которую мы можем непосредственно установить в качестве текущей позиции.
Решая вашу проблему, я предлагаю использовать Vector3.Lerp
для перехода к targetPosition
. После вызова Move
метода в каждом Update
мы можем проверить, достигли ли мы указанной цели; Lerp.Vector3
будет не перерегулирование, поэтому transform.position == targetPosition
становится надежным. Теперь мы можем проверить положение и изменить , targetPosition
чтобы leftPosition
или rightPosition
изменить направление движения, соответственно.
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);
}
Вы можете увидеть это в следующей анимации. Я перевожу синий куб с помощью Vector3.LerpUnclamped
, который дает нам результат, аналогичный простому непроверенному переводу. Я перевожу красный куб, используя Vector3.Lerp
. Оставленный непроверенным, синий куб уходит в забвение; в то время как красный куб останавливается именно там, где я собираюсь. Вы можете прочитать больше об этом типе движения в документации по переполнению стека .
Bools
как_atPosA
и_atPosB
. Неизбежно, вы допустите ошибку, держа их обоих в синхронизации, и это приведет к ошибкам. Лучше сделать вложение,enum
содержащее все позиции (A, B, возможно, другие в будущем), и использовать это