Ricerca…


introduzione

La struttura Vector3 rappresenta una coordinata 3D ed è una delle strutture di backbone della libreria UnityEngine . La struttura Vector3 si trova più comunemente nel componente Transform della maggior parte degli oggetti di gioco, dove è usata per mantenere la posizione e la scala . Vector3 offre buone funzionalità per l'esecuzione di operazioni vettoriali comuni. Puoi leggere di più sulla struttura di Vector3 nell'API di Unity.

Sintassi

  • public Vector3 ();
  • pubblico Vector3 (float x, float y);
  • pubblico 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, distanza di galleggiamento);

Valori statici

La struttura Vector3 contiene alcune variabili statiche che forniscono valori Vector3 comunemente usati. La maggior parte rappresenta una direzione , ma possono comunque essere utilizzati in modo creativo per fornire funzionalità aggiuntive.



Vector3.zero e Vector3.one

Vector3.zero e Vector3.one sono tipicamente usati in connessione con un Vector3 normalizzato ; cioè, un Vector3 cui i valori x , y e z hanno una magnitudine di 1. Come tale, Vector3.zero rappresenta il valore più basso, mentre Vector3.one rappresenta il valore più grande.

Vector3.zero è anche comunemente usato per impostare la posizione di default sulle trasformazioni di oggetti.


La seguente classe usa Vector3.zero e Vector3.one per gonfiare e sgonfiare una sfera.

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



Indicazioni statiche

Le direzioni statiche possono essere utili in numerose applicazioni, con direzione lungo il positivo e il negativo di tutti e tre gli assi. È importante notare che Unity utilizza un sistema di coordinate mancino, che influisce sulla direzione.

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 seguente classe usa le direzioni di Vector3 statiche per spostare gli oggetti lungo i tre assi.

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.



Indice

Valore X y z new Vector3() metodo new Vector3() equivalente
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)

Creare un Vector3

Una struttura Vector3 può essere creata in diversi modi. Vector3 è una struttura e, come tale, in genere dovrà essere istanziata prima dell'uso.


Costruttori

Ci sono tre costruttori incorporati per istanziare un Vector3 .

Costruttore Risultato
new Vector3() Crea una struttura Vector3 con coordinate di (0, 0, 0).
new Vector3(float x, float y) Crea una Vector3 struttura con il dato x ed y coordinate. z sarà impostato a 0.
new Vector3(float x, float y, float z) Crea una struttura Vector3 con le coordinate x , y z indicate.


Conversione da un Vector2 o Vector4

Sebbene rari, è possibile imbattersi in situazioni in cui è necessario trattare le coordinate di una struttura Vector2 o Vector4 come Vector3 . In questi casi, puoi semplicemente passare Vector2 o Vector4 direttamente a Vector3 , senza prima averlo istanziato. Come dovrebbe essere assunto, una struttura Vector2 passerà solo i valori x e y , mentre una classe Vector4 sua w .


Possiamo vedere la conversione diretta nello script seguente.

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.

Applicazione del movimento

La struttura Vector3 contiene alcune funzioni statiche che possono fornire utilità quando si desidera applicare il movimento a Vector3 .

Lerp e LerpUnclamped

Le funzioni di lerp forniscono movimento tra due coordinate basate su una frazione fornita. Dove Lerp consentirà solo il movimento tra le due coordinate, LerpUnclamped consente frazioni che si muovono al di fuori dei confini tra le due coordinate.

Forniamo la frazione di movimento come un float . Con un valore di 0.5 , troviamo il punto medio tra le due coordinate Vector3 . Un valore pari a 0 o 1 restituirà il primo o il secondo Vector3 , rispettosi, in quanto questi valori sono correlati a nessun movimento (restituendo così il primo Vector3 ) o il movimento completato (questo restituisce il secondo Vector3 ). È importante notare che nessuna delle due funzioni consentirà cambiamenti nella frazione di movimento. Questo è qualcosa di cui dobbiamo tener conto manualmente.

Con Lerp , tutti i valori sono bloccati tra 0 e 1 . Questo è utile quando vogliamo fornire il movimento verso una direzione e non vogliamo superare la destinazione. LerpUnclamped può assumere qualsiasi valore e può essere utilizzato per fornire movimento lontano dalla destinazione o oltre la destinazione.


Il seguente script utilizza Lerp e LerpUnclamped per spostare un oggetto a un ritmo costante.

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 in modo molto simile a Lerp ; la differenza principale è che forniamo una distanza effettiva da spostare, invece di una frazione tra due punti. È importante notare che MoveTowards non si estenderà oltre il target Vector3 .

Molto simile a LerpUnclamped , possiamo fornire un valore di distanza negativo per allontanarci dal Vector3 destinazione. In questi casi, non Vector3 mai il target Vector3 , quindi il movimento è indefinito. In questi casi, possiamo considerare il target Vector3 come una "direzione opposta"; fino a quando Vector3 punta nella stessa direzione, rispetto all'inizio Vector3 , il movimento negativo dovrebbe comportarsi normalmente.


Il seguente script usa MoveTowards per spostare un gruppo di oggetti verso un insieme di posizioni usando una distanza livellata.

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

Pensa a SmoothDamp come a una variante di MoveTowards con smoothing incorporato. In base alla documentazione ufficiale, questa funzione è più comunemente utilizzata per eseguire il follow-up della fotocamera.

Insieme alle coordinate Vector3 partenza e di destinazione, dobbiamo anche fornire un Vector3 per rappresentare la velocità e un float rappresenta il tempo approssimativo che dovrebbe impiegare per completare il movimento. A differenza degli esempi precedenti, forniamo la velocità come riferimento , da incrementare, internamente. È importante prendere nota di ciò, poiché la modifica della velocità al di fuori della funzione mentre stiamo ancora eseguendo la funzione può avere risultati indesiderati.

Oltre alle variabili richieste , possiamo anche fornire un float per rappresentare la velocità massima del nostro oggetto, e un float per rappresentare il gap temporale dal precedente richiamo di SmoothDamp all'oggetto. Non abbiamo bisogno di fornire questi valori; per impostazione predefinita, non ci sarà alcuna velocità massima, e il gap temporale sarà interpretato come Time.deltaTime . Ancora più importante, se si chiama la funzione uno per oggetto all'interno di una funzione MonoBehaviour.Update() , non è necessario dichiarare un intervallo di tempo.


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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow