Для спрощення відповіді Vector3
- це звичай, що struct
надається UnityEngine
простором імен. Коли ми створюємо власні class
або struct
типи, ми також повинні визначати його операторів . Таким чином, для >=
оператора немає логіки за замовчуванням . Як зазначив Євген Васильєв , _rect_tfm.position == _positionB
має сенс, тому що ми можемо безпосередньо перевірити Vector3.x
, Vector3.y
і Vector3.z
значення. _rect_tfm.position >= _positionB
не має великого сенсу через те, що а 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, можливо, інші в майбутньому), і використовуючи це