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