Buscar..


Introducción

La estructura Vector3 representa una coordenada 3D, y es una de las estructuras de la UnityEngine troncal de la biblioteca UnityEngine . La estructura Vector3 se encuentra más comúnmente en el componente Transform de la mayoría de los objetos del juego, donde se usa para mantener la posición y la escala . Vector3 proporciona una buena funcionalidad para realizar operaciones vectoriales comunes. Puedes leer más sobre la estructura Vector3 en la API de Unity.

Sintaxis

  • Vector3 público ();
  • Vector3 público (float x, float y);
  • Vector3 público (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, distancia flotante);

Valores estáticos

La estructura Vector3 contiene algunas variables estáticas que proporcionan valores Vector3 comúnmente utilizados. La mayoría representa una dirección , pero aún se pueden usar creativamente para proporcionar funcionalidad adicional.



Vector3.zero y Vector3.one

Vector3.zero y Vector3.one se usan típicamente en conexión con un Vector3 normalizado ; es decir, un Vector3 donde los valores x , y y z tienen una magnitud de 1. Como tal, Vector3.zero representa el valor más bajo, mientras que Vector3.one representa el valor más grande.

Vector3.zero también se usa comúnmente para establecer la posición predeterminada en las transformaciones de objetos.


La siguiente clase usa Vector3.zero y Vector3.one para inflar y desinflar una esfera.

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);
    }
}

A sphere inflated and deflated between Vector3.zero and Vector3.one



Direcciones estáticas

Las direcciones estáticas pueden ser útiles en varias aplicaciones, con dirección a lo largo de los tres ejes positivo y negativo. Es importante tener en cuenta que Unity emplea un sistema de coordenadas para zurdos, que tiene un efecto en la dirección.

In the left-handed coordinate system, the X axis moves to the right, the Y axis moves upwards and the Z axis moves further inwards.


La siguiente clase utiliza las direcciones estáticas Vector3 para mover objetos a lo largo de los tres ejes.

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);
    }
}

Animated cubes moving in the static directions.



Índice

Valor X y z new Vector3() método equivalente 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)

Creando un Vector3

Una estructura Vector3 se puede crear de varias maneras. Vector3 es una estructura, y como tal, normalmente deberá ser instanciada antes de su uso.


Constructores

Hay tres constructores integrados para instanciar un Vector3 .

Constructor Resultado
new Vector3() Crea una estructura Vector3 con coordenadas de (0, 0, 0).
new Vector3(float x, float y) Crea una estructura Vector3 con las coordenadas x e y dadas. z se establecerá en 0.
new Vector3(float x, float y, float z) Crea una estructura Vector3 con las coordenadas x , y y z dadas.


Convertir desde un Vector2 o Vector4

Si bien es poco frecuente, puede encontrarse con situaciones en las que tendría que tratar las coordenadas de una estructura Vector2 o Vector4 como un Vector3 . En tales casos, simplemente puede pasar el Vector2 o Vector4 directamente al Vector3 , sin instanciarlo previamente. Como debe suponerse, una estructura Vector2 solo pasará los valores x e y , mientras que una clase Vector4 omitirá su w .


Podemos ver la conversión directa en el siguiente script.

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);
}

Debug output confirms that both Vector2 and Vector4 have been successfully converted to Vector3.

Aplicando movimiento

La estructura Vector3 contiene algunas funciones estáticas que pueden proporcionar utilidad cuando deseamos aplicar movimiento al Vector3 .

Lerp y LerpUnclamped

Las funciones lerp proporcionan movimiento entre dos coordenadas basadas en una fracción proporcionada. Donde Lerp solo permitirá el movimiento entre las dos coordenadas, LerpUnclamped permite las fracciones que se mueven fuera de los límites entre las dos coordenadas.

Proporcionamos la fracción de movimiento como un float . Con un valor de 0.5 , encontramos el punto medio entre las dos Vector3 . Un valor de 0 o 1 devolverá el primer o segundo Vector3 , respectivamente, ya que estos valores se correlacionan con ningún movimiento (devolviendo así el primer Vector3 ), o con un movimiento completado (devolviendo el segundo Vector3 ). Es importante tener en cuenta que ninguna de las funciones se adaptará al cambio en la fracción de movimiento. Esto es algo que debemos tener en cuenta manualmente.

Con Lerp , todos los valores se fijan entre 0 y 1 . Esto es útil cuando queremos proporcionar movimiento hacia una dirección y no queremos sobrepasar el destino. LerpUnclamped puede tomar cualquier valor y puede usarse para proporcionar movimiento lejos del destino o más allá del destino.


La siguiente secuencia de comandos usa Lerp y LerpUnclamped para mover un objeto a un ritmo constante.

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);
    }
}

The red box moves to the target position, and stops. The blue box continues moving, indefinitely.



MoveTowards

MoveTowards comporta muy similar a Lerp ; la diferencia principal es que proporcionamos una distancia real para moverse, en lugar de una fracción entre dos puntos. Es importante tener en cuenta que MoveTowards no se extenderá más allá del Vector3 objetivo.

Al igual que con LerpUnclamped , podemos proporcionar un valor de distancia negativo para alejarnos del Vector3 objetivo. En tales casos, nunca pasamos del Vector3 objetivo y, por lo tanto, el movimiento es indefinido. En estos casos, podemos tratar el Vector3 objetivo como una "dirección opuesta"; siempre que el Vector3 apunte en la misma dirección, en relación con el Vector3 inicio, el movimiento negativo debería comportarse como normal.


La siguiente secuencia de comandos utiliza MoveTowards para mover un grupo de objetos hacia un conjunto de posiciones utilizando una distancia suavizada.

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);
    }
}

All cubes move outwards from the center, with the red cube stopping at its target destination.



SmoothDamp

Piense en SmoothDamp como una variante de MoveTowards con suavizado incorporado. Según la documentación oficial, esta función es la más utilizada para realizar un seguimiento suave de la cámara.

Junto con las coordenadas de inicio y objetivo de Vector3 , también debemos proporcionar un Vector3 para representar la velocidad y un float represente el tiempo aproximado que debe tomar para completar el movimiento. A diferencia de los ejemplos anteriores, proporcionamos la velocidad como referencia , para ser incrementada, internamente. Es importante tomar nota de esto, ya que cambiar la velocidad fuera de la función mientras aún estamos realizando la función puede tener resultados no deseados.

Además de las variables requeridas , también podemos proporcionar un float para representar la velocidad máxima de nuestro objeto, y un float para representar el intervalo de tiempo desde la llamada de SmoothDamp anterior al objeto. No necesitamos proporcionar estos valores; de forma predeterminada, no habrá velocidad máxima, y ​​el intervalo de tiempo se interpretará como Time.deltaTime . Más importante aún, si está llamando a la función de uno por objeto dentro de un MonoBehaviour.Update() la función, no debe necesitar para declarar un intervalo de tiempo.


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);
    }
}

We can alter the speed at which the object reaches the target by adjusting the maxSpeed and deltaTime parameters.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow