Sök…


Introduktion

Vector3 strukturen representerar en 3D-koordinat och är en av ryggradsstrukturerna i UnityEngine biblioteket. Vector3 strukturen finns oftast i Transform komponenten för de flesta spelobjekt, där den används för att hålla position och skala . Vector3 ger god funktionalitet för att utföra vanliga vektoroperationer. Du kan läsa mer om Vector3 strukturen i Unity API.

Syntax

  • public Vector3 ();
  • public Vector3 (float x, float y);
  • public Vector3 (float x, float y, float z);
  • Vector3.Lerp (Vector3 startPosition, Vector3 targetPosition, float rörelse Fraktion);
  • Vector3.LerpUnclamped (Vector3 startPosition, Vector3 targetPosition, float rörelse Fraktion);
  • Vector3.MoveTowards (Vector3 startPosition, Vector3 targetPosition, float distance);

Statiska värden

Vector3 strukturen innehåller några statiska variabler som ger vanligt använda Vector3 värden. De flesta representerar en riktning , men de kan fortfarande användas kreativt för att ge ytterligare funktionalitet.



Vector3.zero och Vector3.one

Vector3.zero och Vector3.one används vanligtvis i anslutning till en normaliserad Vector3 ; det vill säga en Vector3 där x , y och z värdena har en storlek på 1. Som sådan representerar Vector3.zero det lägsta värdet, medan Vector3.one representerar det största värdet.

Vector3.zero används också ofta för att ställa in standardpositionen för objektomvandlingar.


Följande klass använder Vector3.zero och Vector3.one att blåsa upp och tömma en sfär.

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



Statiska anvisningar

De statiska riktningarna kan vara användbara i ett antal tillämpningar, med riktning längs det positiva och negativa av alla tre axlarna. Det är viktigt att notera att Unity använder ett vänsterhänt koordinatsystem som påverkar riktningen.

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.


Följande klass använder de statiska Vector3 riktningarna för att flytta objekt längs treaxeln.

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.



Index

Värde x y z Motsvarande new Vector3() -metod
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)

Skapa en Vector3

En Vector3 struktur kan skapas på flera sätt. Vector3 är en struktur, och som sådan kommer det vanligtvis att behöva instanseras före användning.


konstruktörer

Det finns tre inbyggda konstruktörer för att instansera en Vector3 .

Konstruktör Resultat
new Vector3() Skapar en Vector3 struktur med koordinater av (0, 0, 0).
new Vector3(float x, float y) Skapar en Vector3 struktur med de givna x och y -koordinaterna. z kommer att ställas in på 0.
new Vector3(float x, float y, float z) Skapar en Vector3 struktur med de givna x , y och z -koordinaterna.


Konvertering från en Vector2 eller Vector4

Även om det är sällsynt kan du stöta på situationer där du skulle behöva behandla koordinaterna för en Vector2 eller Vector4 struktur som en Vector3 . I sådana fall kan du helt enkelt skicka Vector2 eller Vector4 direkt in i Vector3 utan att tidigare instansera den. Som man antar Vector2 en Vector2 struktur endast x och y värden, medan en Vector4 klass kommer att utelämna sin w .


Vi kan se direkt konvertering i nedanstående skript.

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.

Tillämpa rörelse

Vector3 strukturen innehåller några statiska funktioner som kan ge verktyg när vi vill använda rörelse på Vector3 .

Lerp och LerpUnclamped

Lerp-funktionerna ger rörelse mellan två koordinater baserat på en tillhandahållen fraktion. Där Lerp endast tillåter rörelse mellan de två koordinaterna tillåter LerpUnclamped bråk som rör sig utanför gränserna mellan de två koordinaterna.

Vi tillhandahåller en del av rörelsen som en float . Med ett värde på 0.5 hittar vi mittpunkten mellan de två Vector3 -koordinaterna. Ett värde på 0 eller 1 kommer att returnera den första eller andra Vector3 , respektivt, eftersom dessa värden antingen korrelerar till ingen rörelse (därmed returnerar den första Vector3 ), eller fullbordad rörelse (detta returnerar den andra Vector3 ). Det är viktigt att notera att ingen av funktionerna rymmer för förändring i rörelsesfraktionen. Detta är något vi måste redogöra för manuellt.

Med Lerp är alla värden fastklämda mellan 0 och 1 . Detta är användbart när vi vill ge rörelse mot en riktning och inte vill överskrida destinationen. LerpUnclamped kan ta valfritt värde och kan användas för att ge rörelse bort från destinationen eller förbi destinationen.


Följande skript använder Lerp och LerpUnclamped att flytta ett objekt i en jämn takt.

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 uppträder mycket lik Lerp ; kärnskillnaden är att vi tillhandahåller ett faktiskt avstånd att flytta, istället för en bråk mellan två punkter. Det är viktigt att notera att MoveTowards kommer att sträcka sig förbi målet Vector3 .

Precis som med LerpUnclamped kan vi tillhandahålla ett negativt avståndsvärde för att röra Vector3 bort från målet Vector3 . I sådana fall rör vi oss aldrig förbi målet Vector3 , och rörelsen är därför obestämd. I dessa fall kan vi behandla målet Vector3 som en "motsatt riktning"; så länge Vector3 pekar i samma riktning, i förhållande till starten Vector3 , bör negativ rörelse bete sig som normalt.


Följande skript använder MoveTowards att flytta en grupp objekt mot en uppsättning positioner med ett jämnt avstånd.

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

Tänk på SmoothDamp som en variant av MoveTowards med inbyggd utjämning. Enligt officiell dokumentation används den här funktionen oftast för att utföra slät kamera efter.

Tillsammans med start och mål Vector3 koordinater måste vi också tillhandahålla en Vector3 att representera hastigheten och en float representerar ungefärlig tid det bör ta för att slutföra rörelsen. Till skillnad från tidigare exempel tillhandahåller vi hastigheten som en referens , som ska ökas internt. Det är viktigt att notera detta, eftersom att ändra hastighet utanför funktionen medan vi fortfarande utför funktionen kan ha oönskade resultat.

Förutom de erforderliga variablerna kan vi också tillhandahålla en float som representerar maxhastigheten för vårt objekt och en float att representera tidsgapet sedan det tidigare SmoothDamp samtalet till objektet. Vi behöver inte ge dessa värden; som standard kommer det inte att finnas någon maximal hastighet, och tidsgapet tolkas som Time.deltaTime . Ännu viktigare är att om du anropar funktionen en per objekt i en MonoBehaviour.Update() -funktion, bör du inte behöva förklara ett tidsskillnad.


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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow