腳本生命週期

Reset方法的調用機制
Reset方法可以重設爲默認值。當用戶點擊監視面板上的內容按鈕或者首次添加組件時被調用。這個函數只在編輯器模式下被調用。通常用於給定監視面板很好的默認值。

腳本生命週期

接下來,做出一下講解:最先執行的方法是Awake,這是生命週期的開始,用於進行激活時的初始化代碼,一般可以在這個地方將當前腳本禁用:this.enable=false,如果這樣做了,則會直接跳轉到OnDisable方法執行一次,然後其它的任何方法,都將不再被執行。
如果當前腳本處於可用狀態,則正常的執行順序是繼續向下執行OnEnable,當然我們可以在另外一個腳本中實現這個腳本組件的啓動:this.enab=true;
再向下執行,會進行一個判斷,如果Start方法還沒有被執行,則會被執行一次,如果已經被執行了,則不會再被執行。這是個什麼意思呢?我們可以在某個腳本中將組件禁用this.enable=false,再啓用時會轉到OnEnable處執行,這時繼續向下走,發現Start執行過了,將不再被執行。比如說:第一次啓用時,將怪物的初始位置定在了(0,0,0)點,然後怪物可能會發生了位置的變換,後來被禁用了,再次啓用時,不會讓怪物又回到初始的(0,0,0)位置。
繼續向後執行,就是Update了,然後是FixUpdate,再然後是LateUpdate,如果後面寫了Reset,則會又回到Update,在這4個事件間可以進行循環流動。
再向後執行,就進入了渲染模塊(Rendering),非常重要的一個方法就是OnGUI,用於繪製圖形界面。當然,如果你使用了NGUI,這個生命週期的事情你就不用考慮了。
再向後,就是卸載模塊(TearDown),這裏主要有兩個方法OnDisable與OnDestroy。當被禁用(enable=false)時,會執行OnDisable方法,但是這個時候,腳本並不會被銷燬,在這個狀態下,可以重新回到OnEnable狀態(enable=true)。當手動銷燬或附屬的遊戲對象被銷燬時,OnDestroy纔會被執行,當前腳本的生命週期結束。
 
特別要強調的是:這裏雖然可以使用C#來寫代碼,但是這個類構造對象的生命週期,與MonoBehaviour的生命週期,是完全不同的。
 
可以通過如下示例:對腳本進行驗證(兩個腳本添加到同一個遊戲對象上):
腳本1Monster1:
void OnBecameInvisible()
    {
        Debug.Log("invisible");
}

    void OnBecameVisible()
    {
        Debug.Log("visible");
    }
腳本2MonsterController:
    void Awake()
    {
        Debug.Log("awake");
        }

    void OnEnable()
    {
        Debug.Log("enable");
    }

    void Start()
    {
        Debug.Log("start");
    }

    void Update()
    {
        Debug.Log("update");
    }

    void OnGUI()
    {
        Debug.Log("gui");
    }
    void OnDisable()
    {
        Debug.Log("disable");
    }

    void OnDestroy()
    {
        Debug.Log("destroy");
    }
 
事件函數的執行順序
Unity 腳本中有許多按預設順序以腳本身份運行的事件函數。其執行順序如下:
 
加載第一個場景
啓動場景時調用這些函數(爲場景中的每個對象調用一次)。
Awake: 始終在調用任何 Start 函數之前和實例化預設之後調用此函數。(如果遊戲對象 (GameObject) 在啓動期間處於非活動狀態,則直到其處於活動狀態時或調用添加至其本身的任何腳本中的函數時,再調用 Awake 函數。)紅字部分是圖中沒有提到的,特別需要注意!!!綠色的部分通關測試是不正確的
OnEnable: (僅當對象 (Object) 處於活動狀態時調用此函數):程序會在啓用該對象後立即調用此函數。上述現象會在創建了實例化的 MonoBehaviour 後發生,例如加載了級別或對含腳本組件的遊戲對象 (GameObject) 進行實例化後。
 
第一幀更新之前
Start: 只要啓用腳本實例,即可在更新第一幀之前調用 Start 函數。
 
插值幀
OnApplicationPause: 程序檢測到暫停時,會在幀的結尾處調用此函數,這在常規幀更新期間很有效。調用 OnApplicationPause後,程序將運行另一幀來顯示提示暫停狀態的圖形。
 
更新順序
有幾個不同的事件有助於追蹤遊戲邏輯與交互、動畫、相機位置等內容。常用的方法是運行Update() 函數中的大部分任務,但也可使用其他函數。.
 
FixedUpdate: 通常,FixedUpdate() 的調用頻率高於 Update()。如果幀速率較低,則可在一幀中多次調用此函數,如果幀速率較高,則可能完全無法在幀間調用此函數。程序調用 FixedUpdate() 後將立即執行所有物理計算和更新。在 FixedUpdate() 中應用移動計算時,無需將您的值與 Time.deltaTime 相乘。這是因爲,程序是在可靠的計時器上調用FixedUpdate(),與幀速率無關。
Update: 在每幀上調用一次 Update() 函數。它是用於幀更新的主要 workhorse 函數。
LateUpdate: 完成 Update() 調用後,在每幀上調用 LateUpdate()。Update() 中執行的所有計算都將在 LateUpdate() 開始之前結束。LateUpdate() 的常規使用記錄由第三人稱相機跟蹤。如果在 Update() 中移動和旋轉角色,則可在 LateUpdate() 中計算所有相機移動和旋轉。這將確保在相機跟蹤其位置之前完整移動該角色。
 
渲染
OnPreCull: 在相機剔除場景之前調用此函數。相機可見的對象取決於剔除。OnPreCull 函數調用發生在剔除之前。
OnBecameVisible/OnBecameInvisible: 在對象對於相機可見/不可見時調用此函數。
OnWillRenderObject: 如果對象可見,則爲每個相機調用一次此函數。
OnPreRender: 在相機開始渲染場景之前調用此函數。
OnRenderObject: 在完成所有常規場景渲染後調用此函數。此時,可使用 GL 類或 Graphics.DrawMeshNow 繪製自定義幾何圖形。
OnPostRender: 在相機完成場景渲染後調用此函數。
OnRenderImage(僅限專業版): 在完成場景渲染後調用此函數,以便對屏幕圖像進行後處理。
OnGUI: 在每幀上多次調用此函數,以響應 GUI 事件。程序首先將處理 Layout 和 Repaint 事件,然後再處理每個輸入事件的 Layout 和 keyboard/鼠標事件。
OnDrawGizmos 用於在場景視圖中繪製小圖示 (Gizmos),以實現可視化目的。
 
協同程序
正常的協同程序更新是在返回 Update 函數之後運行。協同程序是可自行停止運行 (yield),直到給定的 YieldInstruction 結束再繼續運行的函數。 協同程序 (Coroutines) 的不同用途:
yield; 在下一幀上調用所有 Update 函數後,協同程序將繼續運行。
yield WaitForSeconds(2); 在指定的時間延遲之後,爲此幀調用所有 Update 函數之後繼續運行
yield WaitForFixedUpdate(); 在所有腳本上調用所有 FixedUpdate 後繼續運行
yield WWW 完成 WWW 下載後繼續運行。
yield StartCoroutine(MyFunc); 連接協同程序,並等待 MyFunc coroutine 首先結束。
 
對象 (Object) 被銷燬時
OnDestroy: 完成所有幀更新後,在當前對象的最後一幀上調用此函數(可能爲響應 Object.Destroy 或在關閉場景時銷燬此對象)。
 
退出時
程序將在場景的所有活動對象上調用這些函數:
OnApplicationQuit: 在退出應用程序之前,程序會在所有遊戲對象上調用此函數。在編輯器中,用戶停止播放模式時,程序將調用此函數。在網頁播放器中,此函數會在網頁視圖關閉時調用。
OnDisable: 此函數會在行爲被禁用或不活動時調用。
 
綜上所述,任何給定腳本的執行順序爲:
調用所有 Awake
調用所有 Start
同時進行(朝向可變增量時間)
所有 FixedUpdate 函數
物理模擬
OnEnter/Exit/Stay 觸發函數
OnEnter/Exit/Stay 碰撞函數
 
剛體插值應用 transform.position 和旋轉
OnMouseDown/OnMouseUp 等事件
所有 Update 函數
將動畫優化爲高級、混合並應用動畫,以進行變換
所有 LateUpdate 函數
渲染
 
提示
協同程序在所有 Update 函數結束後運行。

第5單元: 核心類繼承關係(4課時)
GameObject 遊戲物體:是Unity場景中所有實體的基類。
常用變量方法等註釋如下截圖:

重點函數:課題批註。

Component 組件:是一切附加到遊戲物體的基類。

重點方法:課堂批註。
Transform 變換:物體的位置、旋轉和縮放。場景中的每一個物體都有一個Transform。用於儲存並操控物體的位置、旋轉和縮放。每一個Transform可以有一個父級,允許你分層次應用位置、旋轉和縮放。可以在Hierarchy面板查看層次關係。他們也支持計數器(enumerator),因此你可以使用循環遍歷子物體。

Rigidbody 剛體:通過物理模擬控制一個物體的位置。Rigidbody組件控制物體的位置 - 它使物體在重力影響下下落,並可計算物體將怎樣響應碰撞。當操作剛體參數的時候,你應該在FixedUpdate函數中使用它,物理模擬以離散的時間步執行。FixedUpdate函數在每一步之前被立即調用。
使用剛體注意事項:
如果你的模擬看起來像慢動作並且不真實: 這是縮放的問題。如果你的遊戲世界非常大,所以的東西將顯示移動非常慢,確保你所有的模型爲真實世界大小。例如,一個汽車應該有4米長,一個角色約2米高。物體以相同的加速度下落,不論大或小,重或輕。如果你的遊戲世界有較大的縮放,物體仍以相同的加速度下落,但是因爲所有的物體都比較大,物體的下落顯得就比較慢。
Collider 碰撞器:所有碰撞器的基類。

Behavior:是可以被啓用或禁用的組件。

Renderer 渲染器:所有渲染器的一般功能。渲染器是使物體顯示在屏幕上。對於任何遊戲物體或組件它的渲染器可以通過渲染器屬性來訪問。使用這個類可訪問任意物體,網格或粒子系統的渲染器。渲染器可以禁用,使物體不可見(見enabled)。並且材質可以通過它訪問和修改(見material)。

Component派生類Transform、Rigidbody、Collider、Behavior、Renderer都繼承了組件的成員和方法。
Mesh類:一個允許通過腳本來創建和修改meshes的類。網格(meshes)包括頂點和多個三角形數組。三角形數組僅僅是頂點的索引數組,每個三角形包含三個索引。每個頂點可以有一條法線,兩個紋理座標,及顏色和切線。雖然這些是可選的,但是也可以去掉。所有的頂點信息是被儲存在單獨的同等規格的數組中,所以如果你的網格(mesh)有10個頂點,你同樣應該有大小爲10的數組來存儲法線和其它屬性。

大概有3件事情是你想要使用可修改的網格。

  1. 新建立一個網格 :應該總是按照這個順序來做:
    1)爲頂點數組賦值
    2)爲三角形數組賦值
    代碼如下:
    using UnityEngine;
    using System.Collections;

public class example : MonoBehaviour {
public Vector3[] newVertices;
public Vector2[] newUV;
public int[] newTriangles;
void Start() {
Mesh mesh = new Mesh();
GetComponent<MeshFilter>().mesh = mesh;
mesh.vertices = newVertices;
mesh.uv = newUV;
mesh.triangles = newTriangles;
}
}

  1. 每幀修改定點屬性
    1)獲取頂點數組
    2)修改它們
    3)把它們放回網格
    代碼如下:
    using UnityEngine;
    using System.Collections;

public class example : MonoBehaviour {
void Update() {
Mesh mesh = GetComponent<MeshFilter>().mesh;
Vector3[] vertices = mesh.vertices;
Vector3[] normals = mesh.normals;
int i = 0;
while (i < vertices.Length) {
vertices[i] += normals[i] * Mathf.Sin(Time.time);
i++;
}
mesh.vertices = vertices;
}
}

  1. 連續的改變網格的三角形數組值和頂點值
    1)使用Clean刷新
    2)賦予頂點值和其他屬性
    3)賦予索引值
    代碼如下:
    using UnityEngine;
    using System.Collections;

public class example : MonoBehaviour {
public Vector3[] newVertices;
public Vector2[] newUV;
public int[] newTriangles;
void Update() {
Mesh mesh = GetComponent<MeshFilter>().mesh;
mesh.Clear();
mesh.vertices = newVertices;
mesh.uv = newUV;
mesh.triangles = newTriangles;
}
}
注意:調用Clean函數在賦予新的頂點值和三角形索引值之前是非常重要的,Unity總是檢查三角形的索引值,判斷它們是否超出邊界。調用Clear函數後,給頂點賦值,再給三角形數組賦值,以確保沒有超出數組的邊界。

Material 材質:材質類。此類暴露了一個材質的所有屬性,允許對他們進行動畫處理,也可以用它來設置自定義Shader屬性,但是無法通過監視面板訪問屬性。
爲了獲得一個對象使用的材質,可以使用 Renderer.material 屬性:

Light類:用於燈光組件的腳本接口。使用這個控制Unity燈光的各個方面。這個屬性完全匹配顯示在檢視面板中的值。通常燈光是在編輯器中被創建,但是有時通過腳本創建燈光。

Resources類:允許你按照它們的路徑名查找並加載物體。所有位於Assets文件夾下名爲"Resources"的文件夾中的資源,都可以Resources.Load 函數訪問。
在Unity中通常不需要使用路徑名來訪問資源,相反你可以通過聲明一個成員變量來暴露一個資源的引用,然後在檢視面板中指定它。使用這個技巧的時候Unity可以在構建的時候自動計算哪個資源被使用。這從根本上最大限度地減少了實際用於遊戲的資源的尺寸。當你放資源在"Resources"文件夾中時這個不會這麼做,因此所有在"Resources"文件夾中的資源都將被包含在遊戲中。
老版本API VS 新版本API

Time 時間:從Unity獲取時間信息的接口。

Application 應用程序:訪問應用程序的運行時數據。

腳本生命週期

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章