創建并運行腳本:
unity 使用 C# 和 JavaScript 作為腳本語言,在創建一個腳本時會自動創建 Start 和 Update 兩個常用函數。Unity 中會有些特定的函數,這些特定的函數在一定條件下會被調用,稱為必然事件(Certain Events)
名稱 | 觸發條件 | 用途 |
---|---|---|
Awake | 腳本實例被創建時調用 | 用于游戲對象的初始化,注意Awake的執行早于所有的 Start 腳本 |
Start | Update函數第一次運行之前調用 | 用于游戲對象的初始化 |
Update | 每幀調用一次 | 用于更新游戲場景和狀態(和物理狀態有關的更新應該放在FixedUpdate里) |
FixedUpdate | 每個固定物理時間間隔(Physics Time Step)調用一次 | 用于物理狀態的更新 |
LateUpdate | 每幀調用一次(在Update調用之后) | 用于更新游戲場景和狀態,和相機有關的更新一般放在這里FixedUpdate里) |
Awake 早于 Start 調用,Awake在MonoBehavior創建后就立刻調用,Start將在MonoBehavior創建后在該幀Update之前,在該Monobehavior.enabled == true的情況下執行。
在Update 中盡量不要使用耗時過高的函數(例如 GetComponent),因為這樣會大大減少程序的運行效率。如果要使用 GetComponent,應該在初始化的時候把組件的引用保存在變量中。
在Unity中,開發者編寫的每一個腳本都被視為一個自定義組件(Component),游戲對象可以理解為容納各個組件的容器,所以可以通過 Add Component 來將腳本添加到對象中。
首先創建一個腳本,Assets -> Create -> C# Script 命令,命名為 HelloWorld,在Start 函數中填加以下語句
Debug.Log("Hello World!");//輸出Hello World 到 Console 視圖
腳本本身只是一個組件,是無法脫離游戲對象獨立運行的,它必須添加到游戲對象上才會生效。
依次選擇菜單欄中的 GameObject ->Create Empty 命令即可創建一個空游戲對象。再 Inspector 視圖中單擊對象屬性下方的 Add Component 按鈕,在彈出的菜單中依次打開 Scripts -> HelloWorld。這樣就將HelloWorld腳本綁定到新建的游戲對象中。也可以在 Project 視圖中將 HelloWorld 腳本直接拖動到 Inspector 視圖中的 GameObject 對象上來完成綁定操作。
按下播放按鈕,會在 Console 視圖中輸出 “Hello World!”,如果用戶當前編輯器頁面沒有 Console 視圖,可以通過 【Ctrl+Alt+C】組合鍵的方式把該視圖顯示出來。
在 Start 函數中輸出只會輸出一句 “Hello World!”,而如果將上述語句加入到 Update 中,將會每幀輸出一次。
訪問游戲對象和組件:
MonoBehaviour 類
Unity中的腳本都是繼承自MonoBehaviour,它定義了基本的腳本行為,必然事件也是從 MonoBehaviour 繼承而來。除了必然事件, MonoBehaviour還定義了對各種特定事件(例如模型碰撞、鼠標移動)的響應函數,這些函數均以 On 作為開頭。
常用事件響應函數:
名稱 | 用途 |
---|---|
OnMouseEnter | 鼠標移入GUI控件或者碰撞體時調用 |
OnMouseOver | 鼠標停留在GUI控件或者碰撞體時調用 |
OnMouseExit | 鼠標移出GUI控件或者碰撞體時調用 |
OnMouseDown | 鼠標在GUI控件或者碰撞體上按下時調用 |
OnMouseUp | 鼠標按鍵釋放時調用 |
OnTriggerEnter | 當其他碰撞體進入觸發器時調用 |
OnTriggerExit | 當其他碰撞體離開觸發器時調用 |
OnTriggerStay | 當其他碰撞體停留在觸發器時調用 |
OnCollisionEnter | 當碰撞體或者剛體與其他碰撞體或者剛體接觸時調用 |
OnCollisionExit | 當碰撞體或者剛體與其他碰撞體或者剛體停止接觸時調用 |
OnCollisionStay | 當碰撞體或者剛體與其他碰撞體或者剛體保持接觸時調用 |
OnControllerColliderHit | 當控制器移動時與碰撞體發生碰撞時調用 |
OnBecameVisible | 對于任意一個相機可見時調用 |
OnBecameInvisible | 對于任意一個相機不可見時調用 |
OnEnable | 對象啟用或者激活時調用 |
OnDisable | 對象禁用或者取消激活時調用 |
OnDestroy | 腳本銷毀時調用 |
OnGUI | 渲染GUI和處理GUI消息時調用 |
訪問游戲對象:
1.通過名稱查找:
GameObject.Find() 如果場景中存在指定名稱的游戲對象,那么返回該對象的引用,否則返回 null。如果存在多個游戲對象使用同一名稱,那么返回第一個對象的引用。第一個的含義是在 Hierarchy 中排列順序第一個,而不是創建順序。
GameObject player;
palyer = GameObject.Find("player");
2.通過標簽查找 :
GameObject.FindWithTag() 如果場景中存在指定標簽的游戲對象,那么返回該對象的引用
如果想要獲取全部相同標簽的對象,可以通過 FindGameObjectsWithTag() 方法
GameObject player;
GameObject[] enemies;
palyer = GameObject.FindWithTag("player");
enemies = GameObject.FindGameObjectsWithTag("Enemy");
訪問組件:
在Unity中腳本可以被認為是用戶自定義的組件,并且可以添加到游戲對象上來控制游戲對象的行為,而游戲對象則可視為容納各種組件的容器。
對于系統內置的常用組件,Unity 提供了非常便捷的訪問方式,只需要在腳本里直接訪問組件對應的成員變量即可,這些成員變量定義在 MonoBehaviour 中并被腳本繼承了下來。
常用組件及其變量:
組件名稱 | 變量名 | 組件作用 |
---|---|---|
Transform | transform | 設置對象位置、旋轉、縮放 |
Rigibody | rigibody | 設置物理引擎的剛體屬性 |
Renderer | renderer | 渲染物體模型 |
Light | light | 設置燈光屬性 |
Camera | camera | 設置相機屬性 |
Collider | collider | 設置碰撞體屬性 |
Animation | animation | 設置動畫屬性 |
Audio | audio | 設置聲音屬性 |
如果游戲對象上不存在某組件,則該組件對應變量的值將為空值(null)
如果要訪問的組件不屬于上表中的常用組件,或者訪問的是游戲對象上的腳本,可以通過一下函數得到組件的引用
函數名 | 作用 |
---|---|
GetComponent | 得到組件 |
GetComponents | 得到組件列表(用于有多個同類型組件的時候) |
GetComponentlnChildren | 得到對象或對象子物體上的組件 |
GetComponentslnChildren | 得到對象或對象子物體上的組件列表 |
再次強調,GetComponent 比較耗時,因此盡量避免在 Update 中調用這些獲取組件的函數,而是應該在初始化時把組件的引用保存在變量中。
簡單示例:
Example script = GetComponent<Example>();//得到游戲對象上的 Example 腳本組件
Transform t = GetComponent<Transform>(); //得到游戲對象上的 Transform 組件
**除了用函數獲取外, Unity還有一種非常便捷訪問組件或游戲對象的方法,通過聲明訪問權限為 Public 的變量然后將要訪問的組件或者對象賦值給該變量,就可以在腳本中通過變量訪問組件或對象了。
(1)在腳本中添加類型分別為 GameObject 和 Transform 的兩個成員變量,訪問權限設置為 Public,示例代碼如下:
using UnityEngine;
using System.Collections;
public class Hello : MonoBehaviour {
public GameObject cube;
public Transform sphereTransform;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
(2)保存腳本,查看 Player 游戲對象的Inspector視圖,可以看到Hello腳本的視圖參數添加了兩項,正是剛才添加的兩個成員變量,目前沒有對其賦值,所以變量的值均顯示為 None。
(3)用鼠標左鍵在 Hierarchy 視圖中將Cube游戲對象拖到 Inspector 視圖 Cube參數上,接著拖動sphere游戲對象到 Inspector視圖的 Sphere Transform 參數上,完成對兩個成員變量的賦值。
此時Hello 腳本的兩個成員變量分別保存了 Cube 對象的引用和 Sphere 對象的 Transform 組件引用,這樣在腳本中訪問兩個成員變量即可。
常用腳本API
Transform 組件:
transform組件控制游戲對象在Unity場景中的位置、旋轉和大小比例,每個游戲對象都包含一個 Transform 組件。在游戲中如果想要更新玩家位置,設置相機觀察角度都免不了要和Transform組件打交道。
Transform 組件的成員變量:
成員變量 | 說明 |
---|---|
position | 世界坐標系中的位置 |
localPosition | 父對象局部坐標系中的位置 |
eulerAngles | 世界坐標系中以歐拉角表示的旋轉 |
localEulerAngles | 父對象局部坐標系中的歐拉角 |
right | 對象在世界坐標系中的右方向 |
up | 對象在世界坐標系中的上方向 |
forward | 對象在世界坐標系中的前方向 |
rotation | 世界坐標系中以四元數表示的旋轉 |
localRotation | 父對象局部坐標系中以四元數表示的旋轉 |
localScale | 父對象局部坐標系中的縮放比例 |
parent | 父對象的Transform 組件 |
worldToLocalMatrix | 世界坐標系到局部坐標系的變換矩陣 (只讀) |
localToWorldMatrix | 局部坐標系到世界坐標系的變換矩陣(只讀) |
root | 對象層次關系中根對象的 Transform組件 |
childCount | 子孫對象的數量 |
lossyScale | 全局縮放比例(只讀) |
Transform組件的成員函數:
成員函數 | 說明 |
---|---|
Translate | 按指定的方向和距離移動 |
Rotate | 按指定的歐拉角旋轉 |
RotateAround | 按給定旋轉軸和歐拉角進行旋轉 |
LookAt | 旋轉是的自身的前方巷指向目標的位置 |
TransformDirection | 將一個方向從局部坐標系變換到世界坐標系 |
InverseTransformDirection | 講一個方向從世界坐標系變換到局部坐標系 |
TransformPoint | 將一個位置從局部坐標系變換到世界坐標系 |
InverseTransformPoint | 將一個位置從世界坐標系轉換到局部坐標系 |
DetachChildren | 與所有子物體解除父子關系 |
Find | 按名稱查找子對象 |
IsChildOf | 判斷是否是指定對象的子對象 |
Time 類
在 Unity 中可以通過 Time 類來獲取和時間有關的信息,可以用來計算幀速率,調整時間流逝速度等功能。Time 類包含了一個重要的類變量 deltaTime,他表示距上一次調用所用的時間。
Time類成員變量:
成員函數 | 說明 |
---|---|
time | 游戲從開始到現在經理的時間(秒)(只讀) |
timeSinceLevelLoad | 此幀的開始時間(秒)(只讀),從辭官加載完成開始計算 |
deltaTime | 上一幀耗費的時間(秒)(只讀) |
fixedTime | 最近FixedUpdate的時間。該時間從游戲開始計算 |
fixedDeltaTime | 物理引擎和FixedUpdate的更新時間間隔 |
maximumDeltaTime | 一幀的最大耗費時間 |
smoothDeltaTime | Time.deltaTime的平滑淡出 |
timeScale | 時間流逝速度的比例。可用來制作慢動作特效 |
frameCount | 已渲染的幀的總數(只讀) |
realtimeSinceStartup | 游戲從開始到現在經理的真實時間(秒),改時間不會受timeScale影響 |
captureFramerate | 固定幀率設置 |
Random類:
Random類可以用來生成隨機數。
Random類的成員變量:
成員變量 | 說明 |
---|---|
seed | 隨機數生成器種子 |
value | 返回一個0~1之間的隨機浮點數,包含 0 和 1 |
insideUnitSphere | 返回位域半徑為1的求體內的一個隨機點 |
insideUnitCircle | 返回位域半徑為1的圓內的一個隨機點(只讀) |
onUnitSphere | 返回半徑為1的球面上的一個隨機點(只讀) |
rotation | 返回一個隨機旋轉(只讀) |
rotationUniform | 返回一個均勻分布的隨機旋轉(只讀) |
Random類的成員變量:
成員函數 | 說明 |
---|---|
Range | 返回 min 和 max 之間的一個隨機浮點數,包含 min 和 max |
Mathf類
Mathf類的變量:
變量 | 說明 |
---|---|
PI | 圓周率π,即3.14159265358979...(只讀) |
Infinity | 正無窮大 ∞(只讀) |
NegativeInfinity | 負無窮大 - ∞ (只讀) |
Deg2Rad | 度到弧度的轉換系數(只讀) |
Rad2Deg | 弧度到度的轉換系數(只讀) |
Epsilon | 一個很小的浮點數(只讀) |
Mathf類的常用方法:.
常用方法 | 說明 |
---|---|
Sin | 計算角度(單位為弧度)的正弦值 |
Cos | 計算角度(單位為弧度)的余弦值 |
Tan | 計算角度(單位為弧度)的正切值 |
Asin | 計算反正弦值(返回的角度值單位為弧度) |
Acos | 計算反余弦值(返回的角度值單位為弧度) |
Atan | 計算反正切值(返回的角度值單位為弧度) |
Sqrt | 計算平方根 |
Abs | 計算絕對值 |
Min | 返回若干數值中的最小值 |
Max | 返回若干數值中的最大值 |
Pow | Pow(f,p)返回 f 的 p 次方 |
Exp | Exp(p)返回 e 的 p 次方 |
Log | 計算對數 |
Log10 | 計算基為10的對數 |
Ceil | Ceil(f)返回大于或等于 f 的最小整數 |
Floor | Floor(f)返回小于或等于f的最大整數 |
Round | Round(f)返回浮點數 f 進行四舍五入后得到的整數 |
Clamp | 將數值限制在 min 和 max 之間 |
Clamp01 | 將數值限制在 0 和 1 之間 |
Coroutine協同程序
Coroutine也稱為協同程序或者協程,協同程序可以和主線程并行運行,和多線程有些類似。協同程序可以用來實現讓一段程序等待一段時間后繼續運行的效果。
與協同程序有關的函數:
函數 | 說明 |
---|---|
StartCoroutine | 啟動一個協同程序 |
StopCoroutine | 中指一個協同程序 |
StopAllCoroutines | 中指所有協同程序 |
WaitForSeconds | 等待若干秒 |
WaitForFixedUpdate | 等待直到下一次 FixedUpdate調用 |
C#協程例子:
using UnityEngine;
using System.Collections;
public class Hello : MonoBehaviour {
// Use this for initialization
IEnumerator Start () {
Debug.Log ("Starting " + Time.time);
yield return StartCoroutine(WaitAndPrint());//啟動協同程序 WaitAndPrint
print("Done " + Time.time);
}
IEnumerator WaitAndPrint(){
yield return new WaitForSeconds (5f);
print ("WaitAndPrint " + Time.time);
}
}
在C#中,協同程序的返回類型必須為 IEnumerator ,yield 要用 yield return 代替,并且啟動協同程序要用 StartCoroutine 函數。