Unity3D框架執行原理

一、Unity關鍵類繼承關係

(1)、繼承關係如下圖:
在這裏插入圖片描述
用戶定義的每一個類在引擎中都屬於一個組件,引擎中每個Component類定義了GameObject類型的對象,用於申明當前組件所屬的遊戲對象。

二、用戶實現的接口與引擎調用關係

Unity3D引擎爲遊戲開發者提供了腳本語言(例如:C#、Javascript)編寫代碼,基於Unity引擎的開發者通用可通過如下如下幾種方式實現接口的調用:

  • 基於引擎幀更新機制調用用戶實現的接口。
  • 基於引擎的消息事件響應機制調用用戶接口。
  • 引擎的延遲調用機制。
  • 其他直接調用方式。

(1)、基於引擎幀更新機制調用用戶實現的接口
創建Unity引擎的C#腳本文件,會默認爲類生成Start和Update函數,其中Start函數僅在Update函數第一次調用時會被引擎調用,用戶通過Start實現初始化操作,類似於類的構造函數。
Unity引擎爲用戶提供了多種幀更新操作,例如常用的三種更新操作爲:Update、FixedUpdate、LateUpdate,三種Update調用機制不相同,三種函數調用機制如下:
Update:引擎會在每幀更新的過程中遍歷對象並更新該組件的Update函數。
FixedUpdate:引擎以固定時間調用組件的FixedUpdate函數。
LateUpdate:在Update函數調用之後調用,通過該功能可調整腳本執行的順序,例如:當無敵在Update裏移動時,跟隨物體的相機可在LateUpdate裏實現鏡頭移動。
用戶定義組件對象默認繼承MonoBehaviour,用戶實現的每幀更新Update函數於引擎的PlayerLoop函數調用(該函數於Player.cpp實現),其中GetBehaviourManager()是獲取管理Update方式每幀更新的調用方法,其中GetBehaviourManager().update()函數及所屬類的GetBehaviourManager().update()函數內部由CommonUpdate模版實現。用戶實現的FixedUpdate屬於固定時間的調用方式,對應在PlayerLoop函數中調用。GetTimeManager().StepFixedTime()函數會判斷是否需要處理固定時間的相關操作,例如用戶定義的FixedUpdate函數更新邏輯,所有的組件Update調用之後才調用LateUpdate函數。

(2)、基於引擎消息事件的調用機制
Unity引擎提供給用戶感知某些消息類事件的感知,例如某遊戲的EntityCollider.cs文件中實現了EntityCollider::OntriggerEnter方法。
其中OnTriggerEnter爲用戶感知碰撞探測相關事件,OnTriggerEnter函數綁定了kEnterTrigger函數,在PhysicsManager::ProcesssRecordedreports函數內部調用,在判斷當前MessageID爲kEnterTrigger之後,已消息方式調用SendMessage函數讓引擎調用用戶實現的OnTriggerEnter接口。其中PhysicsManager::ProcesssRecordedreports函數由PhysicsManager::FixedUpdate調用,消息處理機制是引擎以固定時間的方式在PhysicsManager類的FixedUpdate方法中不斷調用實現。

(3)、引擎的延遲調用機制
Unity爲用戶提供了延遲調用某方法,對應通過Invoke和InvokeRepeating 函數實現,其中Invoke和InvokeRepeat接口定義如下:
function Invoke (methodName : string, time : float) : void
function InvokeRepeating (methodName : string, time : float, repeatRate : float) : void
Invoke爲延遲調用一次,InvokeRepeating 爲延遲調用多次,延遲調用通過引擎的InvokeDelayed函數實現,延遲調用機制較爲簡單,延遲的時間、重複調用的次數都由用戶控制。

(4)、其他機制
其他機制包括用戶定義的C#函數之間調用,該類調用方式與C++函數調用方式類似,不在進行詳細闡述。

三、Unity整理框架及幀更新機制

Unity引擎將所有重要事件於主線程中實現,如幀更新邏輯、渲染邏輯、碰撞檢測邏輯等,Unity引擎初始化及運行幀更新相關執行流程如下圖所示:
在這裏插入圖片描述
其中UpdateScene負責更新遊戲場景中所有幀更新時間。PlayerLoop函數屬於每幀更細都會調用,該函數負責處理遊戲中所有組件的Update、及消息事件相應處理。
  Unity引擎會以一定間隔時間不斷更新遊戲場景中所有相關事件,每次需要計算下一次幀更新所需的間隔時間,對應時間計算在MainMessageLoop函數實現,通過Sleep方式將執行權切換給其他線程,防止出現CPU 100%的情況。

四、Unity引擎對象鏈表組織方式

每個遊戲都會通過某種方式存儲場景中的所有對象,Unity引擎的場景對象通過GameObjectManager進行管理,GameObjectManager通過STL的List結構存儲了遊戲場景中所有對象,通過遍歷List鏈表便可獲取到遊戲場景中所有對象,Unity通過GameObject::FindGameObjectWithTag函數可通過傳入對象的標識從而獲取到對象指針,函數通過遍歷List鏈表的所有信息查找所需的對象。每個GameObject對象都包含了Tag字段,該字段用於區分不同的對象

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