unity3d
Vector3
Поиск…
Вступление
Vector3
представляет собой трехмерную координату и является одной из UnityEngine
библиотеки UnityEngine
. Структура Vector3
чаще всего встречается в компоненте Transform
большинства игровых объектов, где используется для сохранения положения и масштаба . Vector3
обеспечивает хорошую функциональность для выполнения общих векторных операций. Вы можете больше Vector3
структуре Vector3
в Unity API.
Синтаксис
- public Vector3 ();
- public Vector3 (float x, float y);
- public Vector3 (float x, float y, float z);
- Vector3.Lerp (Vector3 startPosition, Vector3 targetPosition, float movementFraction);
- Vector3.LerpUnclamped (Vector3 startPosition, Vector3 targetPosition, float movementFraction);
- Vector3.MoveTowards (Vector3 startPosition, Vector3 targetPosition, расстояние по плаванию);
Статические значения
Структура Vector3
содержит некоторые статические переменные, которые предоставляют обычно используемые значения Vector3
. Большинство из них представляют собой направление , но они все еще могут быть использованы творчески для обеспечения дополнительной функциональности.
Vector3.zero
и Vector3.one
Vector3.zero
и Vector3.one
обычно используются в связи с нормализованным Vector3
; то есть Vector3
где значения x
, y
и z
имеют величину 1. Таким образом, Vector3.zero
представляет наименьшее значение, в то время как Vector3.one
представляет наибольшее значение.
Vector3.zero
также обычно используется для установки позиции по умолчанию для объектных преобразований.
Следующий класс использует Vector3.zero
и Vector3.one
для раздувания и Vector3.one
сферы.
using UnityEngine;
public class Inflater : MonoBehaviour
{
<summary>A sphere set up to inflate and deflate between two values.</summary>
public ScaleBetween sphere;
///<summary>On start, set the sphere GameObject up to inflate
/// and deflate to the corresponding values.</summary>
void Start()
{
// Vector3.zero = Vector3(0, 0, 0); Vector3.one = Vector3(1, 1, 1);
sphere.SetScale(Vector3.zero, Vector3.one);
}
}
Статические направления
Статические направления могут быть полезны в ряде приложений с направлением вдоль положительной и отрицательной всех трех осей. Важно отметить, что Unity использует левую систему координат, которая влияет на направление.
Следующий класс использует статические направления Vector3
для перемещения объектов вдоль трех осей.
using UnityEngine;
public class StaticMover : MonoBehaviour
{
<summary>GameObjects set up to move back and forth between two directions.</summary>
public MoveBetween xMovement, yMovement, zMovement;
///<summary>On start, set each MoveBetween GameObject up to move
/// in the corresponding direction(s).</summary>
void Start()
{
// Vector3.left = Vector3(-1, 0, 0); Vector3.right = Vector3(1, 0, 0);
xMovement.SetDirections(Vector3.left, Vector3.right);
// Vector3.down = Vector3(0, -1, 0); Vector3.up = Vector3(0, 0, 1);
yMovement.SetDirections(Vector3.down, Vector3.up);
// Vector3.back = Vector3(0, 0, -1); Vector3.forward = Vector3(0, 0, 1);
zMovement.SetDirections(Vector3.back, Vector3.forward);
}
}
Индекс
Значение | Икс | Y | Z | Эквивалентный new Vector3() |
---|---|---|---|---|
Vector3.zero | 0 | 0 | 0 | new Vector3(0, 0, 0) |
Vector3.one | 1 | 1 | 1 | new Vector3(1, 1, 1) |
Vector3.left | -1 | 0 | 0 | new Vector3(-1, 0, 0) |
Vector3.right | 1 | 0 | 0 | new Vector3(1, 0, 0) |
Vector3.down | 0 | -1 | 0 | new Vector3(0, -1, 0) |
Vector3.up | 0 | 1 | 0 | new Vector3(0, 1, 0) |
Vector3.back | 0 | 0 | -1 | new Vector3(0, 0, -1) |
Vector3.forward | 0 | 0 | 1 | new Vector3(0, 0, 1) |
Создание Vector3
Структура Vector3
может быть создана несколькими способами. Vector3
является структурой, и как таковой, как правило, необходимо создать экземпляр перед использованием.
Конструкторы
Существует три встроенных конструктора для создания экземпляра Vector3
.
Конструктор | Результат |
---|---|
new Vector3() | Создает структуру Vector3 с координатами (0, 0, 0). |
new Vector3(float x, float y) | Создает структуру Vector3 с заданными координатами x и y . z будет установлено в 0. |
new Vector3(float x, float y, float z) | Создает структуру Vector3 с заданными координатами x , y и z . |
Преобразование из Vector2
или Vector4
В редких случаях вы можете столкнуться с ситуациями, когда вам нужно будет обрабатывать координаты структуры Vector2
или Vector4
как Vector3
. В таких случаях вы можете просто передать Vector2
или Vector4
непосредственно в Vector3
, не Vector3
ранее. Как следует полагать, структура Vector2
будет передавать только значения x
и y
, тогда как класс Vector4
будет опускать свой w
.
Мы можем видеть прямое преобразование в приведенном ниже скрипте.
void VectorConversionTest()
{
Vector2 vector2 = new Vector2(50, 100);
Vector4 vector4 = new Vector4(50, 100, 200, 400);
Vector3 fromVector2 = vector2;
Vector3 fromVector4 = vector4;
Debug.Log("Vector2 conversion: " + fromVector2);
Debug.Log("Vector4 conversion: " + fromVector4);
}
Применение движения
Структура Vector3
содержит некоторые статические функции, которые могут обеспечить полезность, если мы хотим применить движение к Vector3
.
Lerp
и LerpUnclamped
Функции lerp обеспечивают перемещение между двумя координатами, основанными на заданной фракции. Если Lerp
разрешает движение между двумя координатами, LerpUnclamped
позволяет фракциям, которые перемещаются за пределы границ между двумя координатами.
Мы предоставляем долю движения в виде float
. При значении 0.5
мы находим середину между двумя Vector3
. Значение 0
или 1
вернет первый или второй Vector3
, respectivley, так как эти значения либо коррелируют с отсутствием движения (таким образом, возвращая первый Vector3
), либо завершенным движением (это возвращает второй Vector3
). Важно отметить, что ни одна из функций не будет учитываться при изменении доли движения. Это то, что нам нужно для учета вручную.
С Lerp
все значения зажаты между 0
и 1
. Это полезно, когда мы хотим обеспечить движение к направлению и не хотим перерегулировать пункт назначения. LerpUnclamped
может принимать любое значение, и может быть использован для обеспечения движения от пункта назначения, или мимо цели.
Следующий сценарий использует Lerp
и LerpUnclamped
для LerpUnclamped
перемещения объекта.
using UnityEngine;
public class Lerping : MonoBehaviour
{
/// <summary>The red box will use Lerp to move. We will link
/// this object in via the inspector.</summary>
public GameObject lerpObject;
/// <summary>The starting position for our red box.</summary>
public Vector3 lerpStart = new Vector3(0, 0, 0);
/// <summary>The end position for our red box.</summary>
public Vector3 lerpTarget = new Vector3(5, 0, 0);
/// <summary>The blue box will use LerpUnclamped to move. We will
/// link this object in via the inspector.</summary>
public GameObject lerpUnclampedObject;
/// <summary>The starting position for our blue box.</summary>
public Vector3 lerpUnclampedStart = new Vector3(0, 3, 0);
/// <summary>The end position for our blue box.</summary>
public Vector3 lerpUnclampedTarget = new Vector3(5, 3, 0);
/// <summary>The current fraction to increment our lerp functions by.</summary>
public float lerpFraction = 0;
private void Update()
{
// First, I increment the lerp fraction.
// delaTime * 0.25 should give me a value of +1 every second.
lerpFraction += (Time.deltaTime * 0.25f);
// Next, we apply the new lerp values to the target transform position.
lerpObject.transform.position
= Vector3.Lerp(lerpStart, lerpTarget, lerpFraction);
lerpUnclampedObject.transform.position
= Vector3.LerpUnclamped(lerpUnclampedStart, lerpUnclampedTarget, lerpFraction);
}
}
MoveTowards
MoveTowards
ведет себя очень похоже на Lerp
; основное отличие состоит в том, что мы предоставляем фактическое расстояние для перемещения вместо доли между двумя точками. Важно отметить, что MoveTowards
не будет проходить мимо целевого Vector3
.
Так же, как с LerpUnclamped
, мы можем обеспечить отрицательное значение расстояния , чтобы отойти от цели Vector3
. В таких случаях мы никогда не двигаемся мимо целевого Vector3
, и, следовательно, движение неопределено. В этих случаях мы можем рассматривать целевой Vector3
как «противоположное направление»; пока Vector3
указывает в том же направлении, относительно начала Vector3
, отрицательное движение должно вести себя как обычно.
Следующий скрипт использует MoveTowards
для перемещения группы объектов по отношению к набору позиций с использованием сглаженного расстояния.
using UnityEngine;
public class MoveTowardsExample : MonoBehaviour
{
/// <summary>The red cube will move up, the blue cube will move down,
/// the green cube will move left and the yellow cube will move right.
/// These objects will be linked via the inspector.</summary>
public GameObject upCube, downCube, leftCube, rightCube;
/// <summary>The cubes should move at 1 unit per second.</summary>
float speed = 1f;
void Update()
{
// We determine our distance by applying a deltaTime scale to our speed.
float distance = speed * Time.deltaTime;
// The up cube will move upwards, until it reaches the
//position of (Vector3.up * 2), or (0, 2, 0).
upCube.transform.position
= Vector3.MoveTowards(upCube.transform.position, (Vector3.up * 2f), distance);
// The down cube will move downwards, as it enforces a negative distance..
downCube.transform.position
= Vector3.MoveTowards(downCube.transform.position, Vector3.up * 2f, -distance);
// The right cube will move to the right, indefinetly, as it is constantly updating
// its target position with a direction based off the current position.
rightCube.transform.position = Vector3.MoveTowards(rightCube.transform.position,
rightCube.transform.position + Vector3.right, distance);
// The left cube does not need to account for updating its target position,
// as it is moving away from the target position, and will never reach it.
leftCube.transform.position
= Vector3.MoveTowards(leftCube.transform.position, Vector3.right, -distance);
}
}
SmoothDamp
Подумайте о SmoothDamp
как о варианте MoveTowards
со встроенным сглаживанием. Согласно официальной документации, эта функция чаще всего используется для обеспечения гладкой камеры.
Наряду с начальными и целевыми координатами Vector3
мы также должны предоставить Vector3
для представления скорости, а float
- приблизительное время, необходимое для завершения движения. В отличие от предыдущих примеров, мы предоставляем скорость в качестве эталона , чтобы быть увеличенным внутри. Важно отметить это, поскольку изменение скорости вне функции, пока мы все еще выполняем функцию, может иметь нежелательные результаты.
В дополнение к требуемым переменным мы также можем предоставить float
для представления максимальной скорости нашего объекта и float
для представления временного промежутка с момента предыдущего вызова SmoothDamp
. Нам не нужно предоставлять эти значения; по умолчанию не будет максимальной скорости, а временной интервал будет интерпретироваться как Time.deltaTime
. Что еще более важно, если вы вызываете функцию по одному объекту внутри функции MonoBehaviour.Update()
, вам не нужно MonoBehaviour.Update()
промежуток времени.
using UnityEngine;
public class SmoothDampMovement : MonoBehaviour
{
/// <summary>The red cube will imitate the default SmoothDamp function.
/// The blue cube will move faster by manipulating the "time gap", while
/// the green cube will have an enforced maximum speed. Note that these
/// objects have been linked via the inspector.</summary>
public GameObject smoothObject, fastSmoothObject, cappedSmoothObject;
/// <summary>We must instantiate the velocities, externally, so they may
/// be manipulated from within the function. Note that by making these
/// vectors public, they will be automatically instantiated as Vector3.Zero
/// through the inspector. This also allows us to view the velocities,
/// from the inspector, to observe how they change.</summary>
public Vector3 regularVelocity, fastVelocity, cappedVelocity;
/// <summary>Each object should move 10 units along the X-axis.</summary>
Vector3 regularTarget = new Vector3(10f, 0f);
Vector3 fastTarget = new Vector3(10f, 1.5f);
Vector3 cappedTarget = new Vector3(10f, 3f);
/// <summary>We will give a target time of 5 seconds.</summary>
float targetTime = 5f;
void Update()
{
// The default SmoothDamp function will give us a general smooth movement.
smoothObject.transform.position = Vector3.SmoothDamp(smoothObject.transform.position,
regularTarget, ref regularVelocity, targetTime);
// Note that a "maxSpeed" outside of reasonable limitations should not have any
// effect, while providing a "deltaTime" of 0 tells the function that no time has
// passed since the last SmoothDamp call, resulting in no movement, the second time.
smoothObject.transform.position = Vector3.SmoothDamp(smoothObject.transform.position,
regularTarget, ref regularVelocity, targetTime, 10f, 0f);
// Note that "deltaTime" defaults to Time.deltaTime due to an assumption that this
// function will be called once per update function. We can call the function
// multiple times during an update function, but the function will assume that enough
// time has passed to continue the same approximate movement. As a result,
// this object should reach the target, quicker.
fastSmoothObject.transform.position = Vector3.SmoothDamp(
fastSmoothObject.transform.position, fastTarget, ref fastVelocity, targetTime);
fastSmoothObject.transform.position = Vector3.SmoothDamp(
fastSmoothObject.transform.position, fastTarget, ref fastVelocity, targetTime);
// Lastly, note that a "maxSpeed" becomes irrelevant, if the object does not
// realistically reach such speeds. Linear speed can be determined as
// (Distance / Time), but given the simple fact that we start and end slow, we can
// infer that speed will actually be higher, during the middle. As such, we can
// infer that a value of (Distance / Time) or (10/5) will affect the
// function. We will half the "maxSpeed", again, to make it more noticeable.
cappedSmoothObject.transform.position = Vector3.SmoothDamp(
cappedSmoothObject.transform.position,
cappedTarget, ref cappedVelocity, targetTime, 1f);
}
}