01. Unity優(yōu)化指南

這是摘自Unity官方文檔有關(guān)優(yōu)化的部分纺蛆,原文鏈接:https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity.html
總共分為如下系列:

  1. 采樣分析
  2. 內(nèi)存部分
  3. 協(xié)程
  4. Asset審查
  5. 理解托管堆 【推薦閱讀】
    5.1 上篇:原理负懦,臨時分配內(nèi)存,集合和數(shù)組
    5.2 下篇:閉包,裝箱,數(shù)組
  6. 字符串和文本
  7. 資源目錄
  8. 通用的優(yōu)化方案
  9. 一些特殊的優(yōu)化方案

采樣分析

考慮到優(yōu)化性能的時候,首先必須記住所有的優(yōu)化是從采樣分析開始。對應(yīng)用進(jìn)行采樣發(fā)現(xiàn)問題所在是第一步芍殖,從而對采樣的結(jié)果針對項目的代碼和資源進(jìn)行分析。

工具:

  • iOS:Instrument和XCode Frame Debugger
  • Android:Snapdragon Profiler
  • Intel CPU/GPU的平臺:VTune和Intel GPA
  • PS4:Razor套裝
  • Xbox:Pix工具

這些工具的使用條件是IL2CPP生成的項目谴蔑,因為原生C++代碼能夠提供更加清晰的調(diào)用關(guān)系和方法調(diào)用的時間消耗豌骏,在Mono平臺下做不到這些。

啟動日志的分析

當(dāng)觀察啟動時的跟蹤日志树碱,需要特別關(guān)注兩個關(guān)鍵方法肯适,這兩個方法反映了項目中的配置、資源和代碼如何影響啟動時間成榜。

游戲啟動設(shè)置不同的平臺上略有差異框舔,在大部分平臺上用戶可以看到一個靜態(tài)的啟動界面。

啟動日志

上圖是來自于Instrument工具截取在iOS設(shè)備上運行實例工程的跟蹤日志。在startUnity方法中刘绣,注意UnityInitApplicationGraphicsUnityLoadApplication方法樱溉。

UnityInitApplicationGraphics

這個方法會執(zhí)行一系列的內(nèi)部操作,設(shè)置圖形顯示設(shè)備和初始化Unity的內(nèi)部系統(tǒng)纬凤。除此之外福贞,它還會初始化資源系統(tǒng),導(dǎo)入資源系統(tǒng)包含的所有文件的索引停士。

每個“Resources”目錄中包含的資源文件都屬于資源系統(tǒng)的數(shù)據(jù)挖帘。

【Resources”目錄指的是“Assets”目錄下的“Resources”以及這些“Resources”目錄下的所有子文件夾×导迹】

所以拇舀,如果Resources目錄下的文件非常多,就會造成加載的時間比較長蜻底。

UnityLoadApplication

包含加載和初始化項目中的第一個場景骄崩。這個步驟包括反序列化和實例化場景中所有的數(shù)據(jù),例如編譯Shader薄辅,上傳紋理和實例化GameObject要拂。除此之外,第一個場景中的所有MonoBehaviour對象中的Awake方法都在這個方法內(nèi)執(zhí)行站楚。

這些處理流程意味著脱惰,如果你的Awake回調(diào)方法中有耗時較長的代碼,就會嚴(yán)重拖慢項目的啟動速度源请。要不你就刪除這段代碼枪芒,要不你就把這段代碼放到別的生命周期中執(zhí)行。

運行日志的分析

在啟動部分完成之后谁尸,接著就是PlayerLoop方法了。這是Unity的主循環(huán)纽甘,每幀都會執(zhí)行一次良蛮。

運行日志

上圖中的截圖來自于Unity5.4的某個示例工程,展示了PlayerLoop中值得關(guān)注的幾個方法悍赢。注意PlayerLoop中的方法在不同版本的Unity中可能不同决瞳。

PlayerRender

運行Unity的渲染系統(tǒng),包括剔除不需要顯示的對象左权,計算動態(tài)合批皮胡,給GPU提交繪制指令。圖片特效或者基于渲染的腳本中的回調(diào)(如OnWillRenderObject)都會在這個函數(shù)中執(zhí)行赏迟。一般情形下屡贺,當(dāng)項目是可以UI交互的時候,這個方法會是消耗CPU資源的頭號顧客。

BaseBehaviourManager

調(diào)用三種模板化的CommonUpdate方法甩栈。這些方法調(diào)用當(dāng)前場景中活躍的GameObject上 MonoBehaviour中特定的回調(diào)方法泻仙。

  • CommonUpdate<UpdateManager> 調(diào)用Update回調(diào)
  • CommonUpdate<LateUpdateManager> 調(diào)用LateUpdate回調(diào)。
  • CommonUpdate<FixedUpdateManager> 調(diào)用FixedUpdate回調(diào)量没。

通常來講玉转,BaseBehaviourManager::CommonUpdate<UpdateManager>是最值得關(guān)注的方法,因為它是Unity工程中大部分代碼的入口方法殴蹄。

其他值得關(guān)注的代碼:

UI::CanvasManager

如果工程用到了Unity UI究抓,這個方法會調(diào)用幾個不同的回調(diào)函數(shù)。包括Unity UI的批處理過程和布局更新袭灯;這兩個操作會導(dǎo)致CanvasManager出現(xiàn)在剖析日志列表中刺下。

DelayedCallManager::Update

運行協(xié)程。更多的細(xì)節(jié)可以參見系列文章中“協(xié)程”這一章妓蛮。

PhysicsManager::FixedUpdate

運行PhysX物理系統(tǒng)怠李,這個函數(shù)主要運行PhysX的內(nèi)部代碼,受到當(dāng)前場景中物理組件個數(shù)的影響蛤克,如Rigidbody和Collider組件捺癞。還有,基于物理的回調(diào)也會出現(xiàn)在這個函數(shù)构挤,如OnTriggerStay和OnCollisionStay方法髓介。

如果工程中用到2D物理,在Physics2DManager::FixedUpdate方法下面會出現(xiàn)類似的方法筋现。

腳本方法的分析

當(dāng)IL2CPP轉(zhuǎn)換后的代碼被調(diào)用的時候唐础,可以找到ScriptingInvocation對象。這是Unity的原生代碼過渡到腳本運行環(huán)境下矾飞,執(zhí)行腳本代碼的關(guān)鍵部分一膨。【從技術(shù)細(xì)節(jié)上來講洒沦,當(dāng)使用IL2CPP豹绪,C#的代碼也會被轉(zhuǎn)化成原生代碼。然而編譯后的代碼通過IL2CPP運行框架執(zhí)行方法的過程申眼,和手寫的C++代碼執(zhí)行過程不同】

腳本方法分析

上面的截圖來自Unity5.4上的一個示例工程瞒津。RuntimeInvoker_Void行下面包含的所有函數(shù)都是交叉編譯后的C#代碼,這些方法每幀執(zhí)行一次括尸。

被轉(zhuǎn)化后的方法命名規(guī)則是巷蚪,每個方法是“類名_原始方法名”。在這些跟蹤日志里面濒翻,有EventSystem.Update屁柏,PlayerShooting.Update和一些其他的Update方法啦膜。這些是大多數(shù)MonoBehaviour類中的Update回調(diào)方法。

展開這些方法前联,很容易發(fā)現(xiàn)到底是哪些方法消耗了大部分的CPU時功戚,也包括其他的腳本中的方法,如Unity的API和C# 庫中的代碼似嗤。

上面的跟蹤日志展示了StandaloneInputModule.Process需要給整個UI系統(tǒng)投射射線啸臀,檢測什么觸碰事件正在懸停或者激活某個UI元素烁落。最大的開銷在于遍歷所有的UI元素和檢測鼠標(biāo)的位置是否在這些UI元素的邊界范圍之內(nèi)乘粒。

資源加載

資源加載也會出現(xiàn)在CPU的日志中。資源加載的主要方法是SerializedFile::ReadObject伤塌。這個方法通過執(zhí)行Transfer方法把文件的二進(jìn)制數(shù)據(jù)流和Unity的序列化系統(tǒng)連接起來灯萍。Transfer方法可以在所有的資源類型中找到,如紋理每聪,MonoBehaviour和粒子系統(tǒng)旦棉。

資源加載

上面的截圖展示了場景正在加載的日志。這個過程需要Unity去讀取數(shù)據(jù)和反序列化場景中所有的資源药薯,通過調(diào)用SerializedFile::ReadObject方法下的不同資源類型的Transfer方法绑洛。

通常來講,如果在運行時間存在性能問題童本,而且SerializedFile::ReadObject方法占據(jù)了很大的性能開銷的話真屯,很有可能就是資源加載導(dǎo)致的幀率問題。注意穷娱,在大多數(shù)情況下绑蔫,如果是 SceneManager,Resources和AssetBundle API這些方法發(fā)起同步資源加載的話泵额,SerializedFile::ReadObject方法只能在主線程中看到配深。

這種性能問題可以通過常用的方法解決:使用異步加載,將ReadObject方法交給worker線程去做嫁盲,或者提前加載比較大的資源凉馆。

注意,Transfer調(diào)用在克隆Object的時候也可能會出現(xiàn)亡资,由CloneObject方法調(diào)用。如果CloneObject方法里面調(diào)用了Transfer方法向叉,那么表明資源不是從存儲器中加載锥腻,而是將老Object的數(shù)據(jù)傳遞給了新Object。Unity序列化老的Object并且根據(jù)這些數(shù)據(jù)反序列化出了新的Object母谎。

下篇:內(nèi)存分析

如果覺得文章對您有用瘦黑,請點個贊唄!???

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市幸斥,隨后出現(xiàn)的幾起案子匹摇,更是在濱河造成了極大的恐慌,老刑警劉巖甲葬,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件廊勃,死亡現(xiàn)場離奇詭異,居然都是意外死亡经窖,警方通過查閱死者的電腦和手機坡垫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來画侣,“玉大人冰悠,你說我怎么就攤上這事∨渎遥” “怎么了溉卓?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長搬泥。 經(jīng)常有香客問我桑寨,道長,這世上最難降的妖魔是什么佑钾? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任西疤,我火速辦了婚禮,結(jié)果婚禮上休溶,老公的妹妹穿的比我還像新娘代赁。我一直安慰自己,他們只是感情好兽掰,可當(dāng)我...
    茶點故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布芭碍。 她就那樣靜靜地躺著,像睡著了一般孽尽。 火紅的嫁衣襯著肌膚如雪窖壕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天杉女,我揣著相機與錄音瞻讽,去河邊找鬼。 笑死熏挎,一個胖子當(dāng)著我的面吹牛速勇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坎拐,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼烦磁,長吁一口氣:“原來是場噩夢啊……” “哼养匈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起都伪,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤呕乎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后陨晶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猬仁,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年珍逸,在試婚紗的時候發(fā)現(xiàn)自己被綠了逐虚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,814評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡谆膳,死狀恐怖叭爱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情漱病,我是刑警寧澤买雾,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布,位于F島的核電站杨帽,受9級特大地震影響漓穿,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜注盈,卻給世界環(huán)境...
    茶點故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一晃危、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧老客,春花似錦僚饭、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至尉间,卻和暖如春偿乖,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背哲嘲。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工贪薪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人眠副。 一個月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓古掏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親侦啸。 傳聞我的和親對象是個殘疾皇子槽唾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,728評論 2 351

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,871評論 25 707
  • 111. [動畫系統(tǒng)]如何將其他類型的動畫轉(zhuǎn)換成關(guān)鍵幀動畫? 動畫->點緩存->關(guān)鍵幀 112. [動畫]Unit...
    胤醚貔貅閱讀 12,984評論 3 90
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫光涂、插件庞萍、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,066評論 4 62
  • 好久么有回來住了钝计,但是很安心。 我也不知道為什么在舒適的環(huán)境里我還是那么的鬧心和不安齐佳,我沒辦法和你好好的相處私恬,我控...
    簡書2017閱讀 186評論 0 0
  • 元組
    HFY_Code閱讀 152評論 0 0