Unity腳本開發基礎(摘要)

創建并運行腳本:

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 函數。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容