unity3d
Vector3
Ricerca…
introduzione
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);
}
}
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.
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);
}
}
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);
}
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);
}
}
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);
}
}
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);
}
}