天天看點

Unite Europe案例項目《影子戰術》層級優化經驗分享

在Unite Europe 2017的Keynote主題演講中,我們為大家分享了将主機遊戲《影子戰術》現場移植到移動平台的過程,并分享了遊戲針對移動平台進行的優化。今天這篇文章将為大家分享該遊戲制作過程中總結的開發經驗。

這其中的很多問題隻有當你真正在制作主機遊戲、手機遊戲、或者處理巨量遊戲内容時才會出現。如果在開發的早期就能把這些問題考慮進去,那麼在開發過程中,你會更輕松,而你的遊戲也會更炫酷。

Transform變化消息每當一個GameObject移動、旋轉、縮放時,我們必須通知讓每個與它相關的遊戲系統。渲染、實體、以及該GameObject的每個父子物體,都需要被通知到,以比對它做出的動作。随着遊戲内容的增加,GameObject的數量也會暴漲,僅是發送這些消息的開銷就會成為很大的性能問題。

這是一個NPC以及它的所有組成部件。這張截圖是他們使用Optimize Game Objects(優化遊戲對象)選項,優化了骨骼綁定之後截取的。是以原始版本的NPC,除了所有的遊戲對象和模型結構之外,還有NPC模型的所有骨骼。

這是一個很标準的遊戲設計過程:關卡設計師設定NPC的生成對象。然後在運作時,這些生成對象會執行個體化一個NPC作為其子物體。Enemy_normal是NPC的根節點,它包含了用來控制NPC移動的NavAgent元件。每個NPC都有一堆的子物體來實作NPC的各個功能。這些看起來沒有任何問題。

但這意味着,在每一幀,當NPC移動的時候,它必須通知這個NPC的所有子物體,告訴它們根節點的transform已經發生了變化。每一幀,每一個NPC都會發送成百上千的transform變化消息,占用大量的幀處理時間。

我們在發現Transform變化消息消耗大量幀時間的問題後,與Mimimi Productions進行了讨論,他們将NPC的生成方式做了簡化處理。除了使用Optimize Game Objects之外,他們開始在場景的根節點下生成NPC,并把NPC能力相關的遊戲對象都移到NPC的根節點上,使它們不會成為NavAgent元件的子對象。這樣Nav Agent下面隻剩下NPC的視覺與實體元件。優化過後,在他們的目标硬體平台上的幀率提高了10幀左右。

重要的事,多說幾遍:

每秒鐘提升了10幀!10幀!幀!

沒有影響工作流程。無需返工重做大量的工作。僅僅是在他們現有的内容上做了一點改動。

Transform變化分發

從Unity 5.4開始,我們一直在盡最大努力優化所有與transform和Transform變化消息相關的代碼。我們已經優化了記憶體布局并提供了.SetPositionAndRotation API來避免沒有特定關聯的改變。我們現在允許向系統注冊某個特定的transform,而不是向引擎中的每個系統都廣播Transform變化消息。

正在進行中的一個巨大改變是,我們将逐漸遷移到一個延遲多線程TransformChangeDispatch系統。這讓我們可以将所有的Transform 變化消息形成獨立的隊列,并在主線程之外對它們進行解析。我們正對盡可能多的系統進行遷移,分發這些通知,而不是讓它們在主線程上進行同步處理。

即使有了這些改進,在開發遊戲時你仍要好好考慮你的層級結構。這樣能幫你節約幀執行時間,為你的玩家提供更好的遊戲體驗。

層級結構指南

如果有東西每一幀都會移動,確定它所有的子物體都确實需要了解位置資訊。隻有渲染、實體、音頻或者類似的核心系統才應該出現。

在運作時動态建立的遊戲對象,如果它們沒有必要作為出生點對象的子物體,那就放在場景的根節點下。

你可以很友善的注冊自己生成的所有内容,并通過OnEnable 和OnDisable來向它們傳遞出生點對象的ActiveInHeirarchy狀态。

嘗試将需要移動的物體進行分組,大約每個根節點50個左右的GameObject。這樣,底層系統可以将你的TransformChangeDispatch任務按照每線程最優數量進行分組。可避免出現線程過于繁忙或過于空閑的情況。

結語

感謝Mimimi Productions讓我們使用《影子戰術》作為範例。我們還将為大家分享遊戲開發相關的全局光照和多場景編輯的經驗與教訓,請保持關注!

繼續閱讀