Transform組件決定了GameObject的位置,旋轉(朝向)和縮放,每一個GameObject必須有一個Transform組件。
如果沒有額外說明,這篇文章中的代碼都放在Update方法中。
移動1
通過修改Transform.position我們可以移動一個物體:
void Update () {
transform.position += Vector3.right * speed * Time.deltaTime ;
}
這段代碼會使物體以每秒speed個單位的速度向世界坐標的右邊(x軸)移動。
當已知移動方向和速度的時候,這種方式比下一種方便。
如果將Update內容改成以下代碼:
transform.position += transform.right * speed * Time.deltaTime;
則會朝著物體本身的右邊(物體自身的x軸)移動。
移動2
通過public static Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta)計算出移動過程中的Transform.position,直接賦值:
public class demoScript : MonoBehaviour {
public Vector3 target = Vector3.right * 5;
public float speed;
void Update () {
float step = speed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position, target, step);
}
}
作用是使物體以每秒speed個單位的速度向target移動。
當已知移動終點和速度的時候,這種方式比上一種方便。
移動3
調用public void Translate(Vector3 translation, Space relativeTo = Space.Self)方法。
在Update中輸入以下代碼:
transform.Translate(Vector3.up * speed * Time.deltaTime, Space.World);
作用是使物體以每秒speed個單位的速度向世界坐標的上方(世界y軸)移動。
此方法在已知移動方向和速度的時候比較方便。relativeTo參數的意思是以誰的坐標系為參考坐標系。
移動4
使用Vector3的靜態方法public static Vector3 Lerp(Vector3 a, Vector3 b, float t)計算出起點和終點之間的值,賦值給position,與移動2的方法很相似
public Transform start;
public Transform end;
void Update() {
transform.position = Vector3.Lerp(start.position, end.position, Time.time);
}
參數t只在[0,1]的范圍有效,小于等于0的時候返回起始向量,大于等于1的時候返回終點向量。
旋轉
物體的朝向有兩種表示方式:歐拉角和Quaternion,兩種方式有相同用的作用。
歐拉角:歐拉角由3個參數組成,也就是我們能在Inspector中設置的x、y、z。x表示這個對象繞自己的x軸的旋轉角度。y、z同理.。
這種方法表示旋轉比較直觀。
Quaternion:用四個數來表示旋轉。Unity內部實現的時候是用這種方式表示旋轉的。但是它基于復數并且直覺上不容易理解。Unity建議我們不要直接修改這四個數。
自轉1
調用Transform的方法public void Rotate(Vector3 eulerAngles, Space relativeTo = Space.Self)來改變rotation。
以下代碼使對象每秒鐘繞著自己坐標系的x軸旋轉speed度:
transform.Rotate(Vector3.right * Time.deltaTime * speed);
以下代碼使對象每秒鐘繞著世界坐標系的x軸旋轉speed度:
transform.Rotate(Vector3.right * Time.deltaTime * speed, Space.World);
當已經知道要繞哪一條軸旋轉且知道旋轉的角度時,這種方法更方便。
這個方法有一個重載的版本
public void Rotate(Vector3 axis, float angle, Space relativeTo = Space.Self)
適用于已知旋轉的軸線和速度的情況。
自轉2
使用Vector3的靜態方法public static Vector3 RotateTowards(Vector3 current, Vector3 target, float maxRadiansDelta, float maxMagnitudeDelta)計算出每一幀的角度vector,轉換成Quaternion,賦值給rotation:
Vector3 targetDir = target_transf.position - transform.position;
float step = speed * Time.deltaTime;
Vector3 newDir = Vector3.RotateTowards(transform.forward, targetDir, step, 0.0F);
transform.rotation = Quaternion.LookRotation(newDir);
這段代碼可以使物體的z軸指向targetDir的方向,也就會使得z軸指向target_transf(一個Transform變量)。
這種方法適用于容易算出目標指向的情況。
自轉3
也可以通過Quaternion的方法public static Quaternion RotateTowards(Quaternion from, Quaternion to, float maxDegreesDelta)直接系算出每一幀的Quaternion,直接賦值給rotation:
Vector3 targetDir = target_transf.position - transform.position;
float step = speed * Time.deltaTime;
Quaternion target_Quaternion = Quaternion.LookRotation(targetDir);
transform.rotation = Quaternion.RotateTowards(transform.rotation, target_Quaternion, step);
這段代碼可以使物體的z軸逐漸指向targetDir的方向,也就會使得z軸指向target_transf(一個Transform變量)。
Quaternion.LookRotation(targetDir)的作用就是返回一個與targetDir相同方向的Quaternion變量。
這種方法適用于容易算出目標指向的情況。
繞軸旋轉
Transform的方法:
public void RotateAround(Vector3 point, Vector3 axis, float angle)
point指定一個世界坐標系中的點,axis指定的是軸線方向,物體就繞著經過point的軸線旋轉。
以下代碼使物體繞著世界坐標軸的x軸旋轉,速度是每秒speed度:
transform.RotateAround (Vector3.zero, Vector3.right, speed * Time.deltaTime);
將以上代碼的第一個參數改成new Vector3(10,0,0)也是一樣的效果,因為它們都指定的是同一根軸!
繞物體旋轉
將B作為A的子對象,然后讓A自轉,因為B與A的相對位置不變,所以B會繞著A轉。
但是這一種方法有一種缺陷,那就是A自轉的角速度只能與B公轉的角速度相同。
如何解決這個問題呢?我們可以使用一個影子空對象C,讓其位置始終與A相同,然后將B作為C的子對象,讓C自轉。結果就是B看起來是在繞著A公轉了。并且這個時候可以自由設置A的自轉,而不會影響B的公轉。
這個方法我會在下一篇文章的實例學習中使用,讀者可以對照著理解。