淺談Unity腳本生命周期與執(zhí)行順序
一、腳本生命周期
Unity腳本中的常見必然事件如下表所示
名稱 | 觸發(fā)時(shí)機(jī) | 用途 |
---|---|---|
Awake | 腳本實(shí)例被創(chuàng)建時(shí)調(diào)用 | 用于游戲?qū)ο蟮某跏蓟?,注意Awake的執(zhí)行早于所有腳本的Start函數(shù) |
OnEnable | 當(dāng)對(duì)象變?yōu)榭捎没蚣せ顮顟B(tài)時(shí)被調(diào)用 | 用途 |
Start | Update函數(shù)第一次運(yùn)行之前調(diào)用 | 用于游戲?qū)ο蟮某跏蓟?/td> |
Update | 每幀調(diào)用一次 | 用于更新游戲場(chǎng)景和狀態(tài) |
FixedUpdate | 每個(gè)固定物理時(shí)間間隔調(diào)用一次 | 用于物理狀態(tài)的更新 |
LateUpdate | 每幀調(diào)用一次(在update之后調(diào)用) | 用于更新游戲場(chǎng)景和狀態(tài),和相機(jī)有關(guān)的更新一般放在這里 |
OnGUI | 渲染和處理OnGUI事件 | 用途 |
OnDisable | 當(dāng)前對(duì)象不可用或非激活狀態(tài)時(shí)被調(diào)用 | 用途 |
OnDestroy | 當(dāng)前對(duì)象被銷毀時(shí)調(diào)用 | 用途 |
下面將以代碼來看看這些必然事件的調(diào)用時(shí)機(jī)
新建一個(gè)C#腳本,并添加以下代碼,然后將其掛到任意的游戲?qū)ο笊?/p>
using System.Collections; using System.Collections.Generic; using UnityEngine; public class TestTest : MonoBehaviour { private void Awake() { Debug.Log("Awake"); } private void OnEnable() { Debug.Log("OnEnable"); } // Start is called before the first frame update void Start() { Debug.Log("Start"); } // Update is called once per frame void Update() { Debug.Log("Update"); } private void FixedUpdate() { Debug.Log("FixedUpdate"); } private void LateUpdate() { Debug.Log("LateUpdate"); } private void OnGUI() { Debug.Log("OnGUI"); } private void OnDisable() { Debug.Log("OnDisable"); } private void OnDestroy() { Debug.Log("OnDestroy"); } }
打印結(jié)果如下圖示:
可以發(fā)現(xiàn),Awake, Start函數(shù)都是在游戲?qū)ο蟊粍?chuàng)建時(shí)調(diào)用一次。
當(dāng)游戲過程中調(diào)整腳本的可見狀態(tài)時(shí),會(huì)分別調(diào)用OnEnable, OnDisable函數(shù),而Awake和Start將不會(huì)再調(diào)用,也就是說一旦腳本被掛載上以后,Awake和Start有且僅會(huì)被執(zhí)行一次。
而Update, FixedUpdate, LateUpdate, OnGUI函數(shù)是會(huì)在游戲過程中被多次調(diào)用的(日志窗口右側(cè)的數(shù)字表示該條日志信息打印的次數(shù))。
最后在游戲?qū)ο蟊讳N毀時(shí),會(huì)依次調(diào)用OnDisable, OnDestory函數(shù)。
二、MonoBehavior生命周期圖
下面再放上一張的生命周期圖
三、腳本執(zhí)行順序
在游戲開發(fā)中,不可避免的會(huì)使用許多腳本,那么如何確定不同腳本之間調(diào)用的先后順序呢
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Test1 : MonoBehaviour { // Start is called before the first frame update void Start() { Debug.Log("start 1"); } private void Awake() { Debug.Log("awake 1"); } // Update is called once per frame void Update() { Debug.Log("update 1"); } }
將上面的代碼依次添加到Test1, Test2和Test3腳本中(適當(dāng)修改打印的日志),并掛載到不同的游戲?qū)ο笊稀?br />
掛載的順序?yàn)橄葤燧dTest3,再掛載Test2,最后掛載Test1
打印結(jié)果如下圖所示
打印結(jié)果是先打印Test1的,再打印Test2,最后打印Test3。
其實(shí)腳本的執(zhí)行順序與掛載到游戲?qū)ο笊系南群箜樞蛴嘘P(guān)。最先被掛載的最后執(zhí)行,最后被掛載的最先執(zhí)行(如果讀者有疑惑,可以不斷調(diào)整腳本的掛載順序,看日志打印與上述結(jié)論是否相符)。
需要注意的是,無論多個(gè)腳本的執(zhí)行順序如何,但所有腳本的Awake函數(shù)一定會(huì)比所有的Start函數(shù)先執(zhí)行完,所有的Start函數(shù)一定也會(huì)比所有的Update函數(shù)先執(zhí)行完,其他有順序的生命周期函數(shù)也是類似的(從上圖的日志信息中也可以看出)。
四、自定義執(zhí)行順序
有時(shí)可能有這樣的需求,A腳本中的屬性實(shí)例化可能需要用到B腳本中的屬性,所以在A腳本屬性實(shí)例化時(shí),必須保證B腳本已經(jīng)被實(shí)例化完畢。當(dāng)然我們可以通過先掛在A腳本再掛載B腳本來實(shí)現(xiàn)。但在實(shí)際開發(fā)中,用到的腳本中多,很難去記住各個(gè)腳本掛載的先后順序。所以Unity提供了Script Execution Order配置項(xiàng),來配置多個(gè)腳本的執(zhí)行順序。
在工程面板中任意點(diǎn)擊選中一個(gè)腳本文件,在屬性面板中會(huì)出現(xiàn)該腳本的詳細(xì)信息,選擇右上角的Execution Order...
,打開如下圖所示界面
點(diǎn)擊“+”可以添加腳本,為其設(shè)置order值,order值越小的越先執(zhí)行,order值越大的越后執(zhí)行
以上就是淺談Unity腳本生命周期與執(zhí)行順序的詳細(xì)內(nèi)容,更多關(guān)于Unity 生命周期的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
C#運(yùn)用FileInfo類實(shí)現(xiàn)拷貝文件的方法
這篇文章主要介紹了C#運(yùn)用FileInfo類實(shí)現(xiàn)拷貝文件的方法,需要的朋友可以參考下2014-07-07Unity實(shí)現(xiàn)移動(dòng)端手勢(shì)解鎖功能
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)移動(dòng)端手勢(shì)解鎖功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-07-07C#實(shí)現(xiàn)JSON字符串序列化與反序列化的方法
在這篇文章中,我們將會(huì)學(xué)到如何使用C#,來序列化對(duì)象成為Json格式的數(shù)據(jù),以及如何反序列化Json數(shù)據(jù)到對(duì)象。2017-01-01WPF+ASP.NET?SignalR實(shí)現(xiàn)簡(jiǎn)易在線聊天功能的示例代碼
這篇文章將以一個(gè)簡(jiǎn)單的聊天示例,簡(jiǎn)述如何通過WPF+ASP.NET?SignalR實(shí)現(xiàn)消息后臺(tái)通知,僅供學(xué)習(xí)分享使用,如有不足之處,還請(qǐng)指正2022-09-09C#結(jié)合JavaScript實(shí)現(xiàn)手寫板簽名效果
這篇文章主要為大家詳細(xì)介紹了C#如何結(jié)合JavaScript實(shí)現(xiàn)手寫板寫字并上傳到服務(wù)器進(jìn)行處理,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04C# 漢字轉(zhuǎn)化拼音的簡(jiǎn)單實(shí)例代碼
C# 漢字轉(zhuǎn)化拼音的簡(jiǎn)單實(shí)例代碼,需要的朋友可以參考一下2013-04-04