Recherche…


Introduction

La structure Vector3 représente une coordonnée 3D et constitue l'une des structures de base de la bibliothèque UnityEngine . La structure Vector3 se trouve le plus souvent dans la composante Transform de la plupart des objets de jeu, où elle est utilisée pour conserver la position et l' échelle . Vector3 fournit de bonnes fonctionnalités pour effectuer des opérations vectorielles courantes. Vous pouvez en savoir plus sur la structure Vector3 dans l'API Unity.

Syntaxe

  • vecteur public3 ();
  • 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, distance flottante);

Valeurs statiques

La structure Vector3 contient des variables statiques qui fournissent des valeurs Vector3 couramment utilisées. La plupart représentent une direction , mais ils peuvent toujours être utilisés de manière créative pour fournir des fonctionnalités supplémentaires.



Vector3.zero et Vector3.one

Vector3.zero et Vector3.one sont généralement utilisés en connexion avec un Vector3 normalisé ; c'est-à-dire un Vector3 où les valeurs x , y et z ont une magnitude de 1. En tant que tel, Vector3.zero représente la valeur la plus faible, tandis que Vector3.one représente la valeur la plus élevée.

Vector3.zero est également couramment utilisé pour définir la position par défaut sur les transformations d'objets.


La classe suivante utilise Vector3.zero et Vector3.one pour gonfler et dégonfler une sphère.

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



Directions statiques

Les directions statiques peuvent être utiles dans un certain nombre d'applications, la direction étant positive et négative sur les trois axes. Il est important de noter que Unity utilise un système de coordonnées pour gaucher, ce qui a une incidence sur la direction.

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 classe suivante utilise les directions statiques Vector3 pour déplacer des objets le long des trois axes.

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

Valeur X y z new Vector3() méthode new Vector3() équivalente
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)

Créer un vecteur3

Une structure Vector3 peut être créée de plusieurs manières. Vector3 est une structure et, en tant que telle, devra généralement être instanciée avant utilisation.


Constructeurs

Il y a trois constructeurs intégrés pour instancier un Vector3 .

Constructeur Résultat
new Vector3() Crée une structure Vector3 avec les coordonnées de (0, 0, 0).
new Vector3(float x, float y) Crée une structure Vector3 avec les coordonnées x et y . z sera mis à 0.
new Vector3(float x, float y, float z) Crée une structure Vector3 avec les x , y et z .


Conversion à partir d'un Vector2 ou Vector4

Bien que cela soit rare, vous pouvez rencontrer des situations où vous devrez traiter les coordonnées d'une structure Vector2 ou Vector4 tant que Vector3 . Dans de tels cas, vous pouvez simplement passer le Vector2 ou le Vector4 directement dans le Vector3 , sans l’instancier au préalable. Comme il faut le supposer, une structure Vector2 ne transmettra que les valeurs x et y , tandis qu'une classe Vector4 omettra son w .


Nous pouvons voir une conversion directe dans le script ci-dessous.

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.

Mouvement d'application

La structure Vector3 contient des fonctions statiques pouvant être utiles lorsque vous souhaitez appliquer un mouvement au Vector3 .

Lerp et LerpUnclamped

Les fonctions lerp fournissent un mouvement entre deux coordonnées basées sur une fraction fournie. Lorsque Lerp ne permet que le mouvement entre les deux coordonnées, LerpUnclamped permet des fractions qui se déplacent en dehors des limites entre les deux coordonnées.

Nous fournissons la fraction de mouvement comme un float . Avec une valeur de 0.5 , on trouve le point milieu entre les deux coordonnées Vector3 . Une valeur de 0 ou 1 renverra le premier ou le deuxième Vector3 , respectivement, car ces valeurs sont soit corrélées à aucun mouvement (renvoyant ainsi le premier Vector3 ), soit au mouvement terminé (ceci renvoyant le deuxième Vector3 ). Il est important de noter qu'aucune des deux fonctions ne permettra de modifier la fraction de mouvement. C'est quelque chose que nous devons prendre en compte manuellement.

Avec Lerp , toutes les valeurs sont bloquées entre 0 et 1 . Ceci est utile lorsque vous souhaitez vous déplacer vers une direction et que vous ne souhaitez pas dépasser la destination. LerpUnclamped peut prendre n'importe quelle valeur et peut être utilisé pour se déplacer à partir de la destination ou au- delà de la destination.


Le script suivant utilise Lerp et LerpUnclamped pour déplacer un objet à un rythme constant.

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 se comporte très similaire à Lerp ; La différence principale est que nous fournissons une distance réelle à déplacer, au lieu d'une fraction entre deux points. Il est important de noter que MoveTowards ne dépassera pas le Vector3 .

Tout comme avec LerpUnclamped , nous pouvons fournir une valeur de distance négative pour nous éloigner du Vector3 cible. Dans de tels cas, nous ne Vector3 jamais le Vector3 , et le mouvement est donc indéfini. Dans ces cas, nous pouvons traiter la cible Vector3 comme une "direction opposée"; tant que le Vector3 pointe dans la même direction, par rapport au Vector3 , le mouvement négatif doit se comporter normalement.


Le script suivant utilise MoveTowards pour déplacer un groupe d'objets vers un ensemble de positions en utilisant une distance lissée.

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

Considérez SmoothDamp comme une variante de MoveTowards avec un lissage intégré. Selon la documentation officielle, cette fonction est la plus utilisée pour effectuer des suivis de caméra en douceur.

En Vector3 coordonnées Vector3 départ et cible, nous devons également fournir un Vector3 pour représenter la vélocité et un float représentant le temps approximatif nécessaire pour terminer le mouvement. Contrairement aux exemples précédents, nous fournissons la vitesse comme référence , à incrémenter, en interne. Il est important de prendre note de ceci, car la modification de la vitesse en dehors de la fonction pendant que nous exécutons encore la fonction peut avoir des résultats indésirables.

En plus des variables requises , nous pouvons également fournir un float pour représenter la vitesse maximale de notre objet et un float pour représenter l'intervalle de temps écoulé depuis le précédent appel SmoothDamp à l'objet. Nous n'avons pas besoin de fournir ces valeurs; par défaut, il n'y aura pas de vitesse maximale et l'intervalle de temps sera interprété comme Time.deltaTime . Plus important encore, si vous appelez la fonction un par objet dans une fonction MonoBehaviour.Update() , vous ne devriez pas avoir à déclarer un intervalle de temps.


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
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow