天天看點

Component 元件腳本及其基本生命周期【Unity程式設計】 Component 元件腳本及其基本生命周期

【Unity程式設計】 Component 元件腳本及其基本生命周期

轉載位址:http://blog.csdn.net/andrewfan

3.1元件 Component

元件是Unity中最核心的一個概念,它是一切程式設計的基礎。沒有元件,也就沒有了Unity程式設計。

打開一個新Unity工程,我們在Project面闆中右鍵可以直接建立出一個C#腳本。

Component 元件腳本及其基本生命周期【Unity程式設計】 Component 元件腳本及其基本生命周期

腳本的内容如下:

Component 元件腳本及其基本生命周期【Unity程式設計】 Component 元件腳本及其基本生命周期
using UnityEngine;
using System.Collections;

public class NewBehaviourScript : MonoBehaviour {

    // Use this for initialization
    void Start () {
    
    }
    
    // Update is called once per frame
    void Update () {
    
    }
}      
Component 元件腳本及其基本生命周期【Unity程式設計】 Component 元件腳本及其基本生命周期

     預設的腳本繼承自MonoBehavior類,這個類是通常的自定義腳本元件繼承類,也就是我們自己所編寫的腳本的父類。而Unity内部元件,如相機等是繼承自

MonoBehavior的父類Behavior或者再上層的父類Component。Unity為何要分成三個級别繼承?從Component到Behavior隻是增加了一個是否可以enable

的屬性,用于差別有些元件是可以禁用的,而有些元件是不可以的。而從Behavior到MonoBehavior,則純粹是為了Unity程式員準備的,因為它增加了很多響應

消息,包括上面代碼中看到的Start、Update以及後面提到的LateUpdate、FixedUpdate等消息。這些消息均是為了讓程式員可以友善地控制和響應元件,而這

些消息對于Unity内置元件來說它是不需要的,它内部自己知道什麼時候需要進行啟動、更新等等操作。

     是以,我們嘗試參考MonoBehavior的文檔,将常見的消息響應全部都列印到控制台上,于是代碼看起來是這樣:

Component 元件腳本及其基本生命周期【Unity程式設計】 Component 元件腳本及其基本生命周期
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");
    }
}      
Component 元件腳本及其基本生命周期【Unity程式設計】 Component 元件腳本及其基本生命周期

附加的Debuger類,用于列印消息,這裡在顯示消息的同時,記錄了目前畫面運作的幀數,以便于我們觀察函數調用的次序以及時機:

Component 元件腳本及其基本生命周期【Unity程式設計】 Component 元件腳本及其基本生命周期
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);
        }
    }
}      
Component 元件腳本及其基本生命周期【Unity程式設計】 Component 元件腳本及其基本生命周期

準備好代碼之後,在場景中建立一個Cube(其實任意GameObject都可以),将TestComponenets拖放其上,然後嘗試啟動運作,并且在Cube的TestComponenets元件上,

将勾選狀态關閉再打開,可以看到控制台輸出的内容。而後停止運作,将上述代碼中的注釋去掉,暴露出幾個Update方法,再次運作以便檢視結果。

最終,我們可以得出如下結論:

  • Awake 方法:當GameObject被啟用時,立刻被執行,中文的字面意思就是說,元件已經蘇醒,但是它還沒有執行,隻是準備好了而已。隻執行一次。
  • OnEnable方法:當元件被啟用時(如果GameObject都沒啟用,元件更談不上啟用),立刻執行,當多啟用時反複執行。
  • OnDisable方法:與OnEnable對應,當元件被禁用時,立刻執行,當多禁用時反複執行。
  • Start方法:當元件被啟用後的下一幀,才會被執行。隻執行一次。【特别注意,這裡是下一幀,如果不注意的話,在資源加載方面可能會出現問題】
  • OnDestroy方法:當元件被銷毀時執行。
  • Update:每幀執行一次,每秒重新整理次數取決于硬體圖像的重新整理速度。
  • LateUpdate:每幀執行一次,後于Update執行,這裡一般用作繪制到螢幕的最後處理(如無此特殊需要,用Update即可)。
  • FixedUpdate:預設按每隔0.02秒(具體時間可以設定)執行一次,與圖像重新整理率無關,用于實體邏輯計算。

正常情況下,執行的順序是如下圖:

Component 元件腳本及其基本生命周期【Unity程式設計】 Component 元件腳本及其基本生命周期

也就是說,在Awake、OnEnable、Start之後開始幾種Update循環。

一般OnEnable用作處理開啟和關閉元件時的開關量轉換,那麼對于此元件的初始化我們可以寫在Awake和Start中。

由于Awake是加載和啟用GameObject後立刻執行的,是以,如果本元件跟随GameObject加載後,應該立刻初始化本元件的共有成員,如果這些成員需要被其它代碼所通路的話。

因為如果放在Start中初始化的話,那麼還需要等待一幀,而這一幀過程中,很可能已經發生了對這些共有成員的通路,而此時尚未初始化。是以應該避免這種情況出現。

我們暫時将其成為二階段初始化,以便更好的記憶。在後續的章節中我們會有更多的展現。