【Unity程式設計】 Component 元件腳本及其基本生命周期
轉載位址:http://blog.csdn.net/andrewfan
3.1元件 Component
元件是Unity中最核心的一個概念,它是一切程式設計的基礎。沒有元件,也就沒有了Unity程式設計。
打開一個新Unity工程,我們在Project面闆中右鍵可以直接建立出一個C#腳本。
腳本的内容如下:
using UnityEngine;
using System.Collections;
public class NewBehaviourScript : MonoBehaviour {
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
預設的腳本繼承自MonoBehavior類,這個類是通常的自定義腳本元件繼承類,也就是我們自己所編寫的腳本的父類。而Unity内部元件,如相機等是繼承自
MonoBehavior的父類Behavior或者再上層的父類Component。Unity為何要分成三個級别繼承?從Component到Behavior隻是增加了一個是否可以enable
的屬性,用于差別有些元件是可以禁用的,而有些元件是不可以的。而從Behavior到MonoBehavior,則純粹是為了Unity程式員準備的,因為它增加了很多響應
消息,包括上面代碼中看到的Start、Update以及後面提到的LateUpdate、FixedUpdate等消息。這些消息均是為了讓程式員可以友善地控制和響應元件,而這
些消息對于Unity内置元件來說它是不需要的,它内部自己知道什麼時候需要進行啟動、更新等等操作。
是以,我們嘗試參考MonoBehavior的文檔,将常見的消息響應全部都列印到控制台上,于是代碼看起來是這樣:
using UnityEngine;
using System.Collections;
using Assets.AndrewBox.Util;
public class TestComponenets : MonoBehaviour
{
void Awake()
{
Debuger.LogAtFrame("Awake");
}
void Start ()
{
Debuger.LogAtFrame("Start");
}
// Update is called once per frame
void Update ()
{
//Debuger.LogAtFrame("Update");
}
void LateUpdate()
{
//Debuger.LogAtFrame("LateUpdate");
}
void FixedUpdate()
{
//Debuger.LogAtFrame("FixedUpdate");
}
void OnEnable()
{
Debuger.LogAtFrame("OnEnable");
}
void OnDisable()
{
Debuger.LogAtFrame("OnDisable");
}
void OnDestroy()
{
Debuger.LogAtFrame("OnDestroy");
}
}
附加的Debuger類,用于列印消息,這裡在顯示消息的同時,記錄了目前畫面運作的幀數,以便于我們觀察函數調用的次序以及時機:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;
namespace Assets.AndrewBox.Util
{
public static class Debuger
{
public static void LogAtFrame(string infor)
{
Debug.Log("["+Time.frameCount+"]"+infor);
}
}
}
準備好代碼之後,在場景中建立一個Cube(其實任意GameObject都可以),将TestComponenets拖放其上,然後嘗試啟動運作,并且在Cube的TestComponenets元件上,
将勾選狀态關閉再打開,可以看到控制台輸出的内容。而後停止運作,将上述代碼中的注釋去掉,暴露出幾個Update方法,再次運作以便檢視結果。
最終,我們可以得出如下結論:
- Awake 方法:當GameObject被啟用時,立刻被執行,中文的字面意思就是說,元件已經蘇醒,但是它還沒有執行,隻是準備好了而已。隻執行一次。
- OnEnable方法:當元件被啟用時(如果GameObject都沒啟用,元件更談不上啟用),立刻執行,當多啟用時反複執行。
- OnDisable方法:與OnEnable對應,當元件被禁用時,立刻執行,當多禁用時反複執行。
- Start方法:當元件被啟用後的下一幀,才會被執行。隻執行一次。【特别注意,這裡是下一幀,如果不注意的話,在資源加載方面可能會出現問題】
- OnDestroy方法:當元件被銷毀時執行。
- Update:每幀執行一次,每秒重新整理次數取決于硬體圖像的重新整理速度。
- LateUpdate:每幀執行一次,後于Update執行,這裡一般用作繪制到螢幕的最後處理(如無此特殊需要,用Update即可)。
- FixedUpdate:預設按每隔0.02秒(具體時間可以設定)執行一次,與圖像重新整理率無關,用于實體邏輯計算。
正常情況下,執行的順序是如下圖:
也就是說,在Awake、OnEnable、Start之後開始幾種Update循環。
一般OnEnable用作處理開啟和關閉元件時的開關量轉換,那麼對于此元件的初始化我們可以寫在Awake和Start中。
由于Awake是加載和啟用GameObject後立刻執行的,是以,如果本元件跟随GameObject加載後,應該立刻初始化本元件的共有成員,如果這些成員需要被其它代碼所通路的話。
因為如果放在Start中初始化的話,那麼還需要等待一幀,而這一幀過程中,很可能已經發生了對這些共有成員的通路,而此時尚未初始化。是以應該避免這種情況出現。
我們暫時将其成為二階段初始化,以便更好的記憶。在後續的章節中我們會有更多的展現。