#每天一個小目標#Unity技術分享(十)

【技術小札】是UWA推出的技術交流欄目,我們會將開發團隊中反饋的常見問題加以總結並梳理在此,以供大家參考。本期我們收集到幾個關於內存和UGUI的問題,小編覺得非常系統,值得大家借鑒哦。

UWA技術QQ群:465082844

UI輸入

Q1:在使用NGUI時,我們通常會將很多小圖打成一個大的圖集,以優化內存和Draw Call。而在UGUI時代,UI所使用的Image必須是Sprite;Unity提供了SpritePacker。 它的工作流程和UGUI Atlas Paker有較大的差別。在Unity Asset中,我們壓根看不到圖集的存在。 問題是:

1. SpritePacker大概的工作機制是什麼樣的?

2. 如果Sprite沒有打包成AssetBundle,直接在GameObject上引用,那麼在Build時Unity會將分散的Sprite拼接在一起么?如果沒有拼接,那SpritePacker是不是只會優化Draw Call,內存佔用上和不用SpritePacker的分離圖效果一樣?

3. 如果將Sprite打成AssetBundle,AssetBundle中的資源是分散的Sprite嗎?如果不是,不同的AssetBundle中引用了兩張Sprite,這兩張Sprite恰好用SpritePacker拼在了一起,是不是就會存在兩份拼接的Sprite集?

4. 如果想使用NGUI Atlas Packer的工作流程,改如何去實現?

  1. 簡單來說,UGUI和 NGUI 類似,但是更加自動化。只需要通過設定 Packing Tag 即可指定哪些 Sprite 放在同一個 Atlas 下。

  2. 可以通過 Edit -> Project Settings -> Editor -> Sprite Packer 的 Mode 來設置是否起效,何時起效(一種是進入 Play Mode 就生效,一種是 Build 時才生效)。所以只要不選 Disabled,Build 時就會把分散的 Sprite 拼起來。

  3. 可以認為 Sprite 就是一個殼子,實際上本身不包含紋理資源,所以打包的時候會把Atlas 打進去。如果不用依賴打包,那麼分開打兩個 Sprite 就意味各自的AssetBundle 里都會有一個 Atlas。

  4. 可以通過第三方工具(如 Texture Packer)製作 Atlas,導出 Sprite 信息(如,第 N 個 Sprite 的 Offset 和 Width,Height 等),然後在 Unity 中通過腳本將該 Atlas 轉成一個 Multiple Mode 的 Sprite 紋理(即一張紋理上包含了多個 Sprite),同時禁用 Unity 的 Sprite Packer 即可。

兩種做法各有利弊,建議分析一下兩種做法對於自身項目的合適程度來進行選擇。

內存管理

Q2:同樣的App,安裝在不同的機型上,使用同樣的自動化腳本進行自動化測試,App的內存消耗(ADB Dumpsys Meminfo)在不同的機型上結果迥異,有些機型只有200MB多的內存消耗,有些機型高達600MB。我們已經分析過OpenGL ES 2.0和OpenGL ES 3.0對ETC2貼圖解壓的影響。200MB左右的機型有些是ES2.0,600MB消耗的機型有些是ES3.0的,並且多次測試可重現。請問你們如何分析這個問題?是否有標準來確定遊戲真正的內存消耗?

Android系統的內存消耗是根據晶元、OS的不同而不同的。ADB反饋出來的PSS其實僅是本機當前該App線程的內存消耗,該值與其他機器的信息其實是沒有任何可比性的。

Unity的項目,其內存我們建議主要還是通過Profiler來看其內存消耗。因為它表示的是引擎開闢和分配的真實物理內存。

內存管理

Q3:首先用戶或者產品只關心整體消耗,並不會以Profiler為準,內存不足的崩潰也不會以Profiler正常而消失。其次,我們降低Profiler統計的消耗後,OS的消耗也會大大降低,甚至下降的更多。我們據此判斷:這兩個數字不一樣,但應該是有聯繫的。我們想知道聯繫是什麼?

可以這樣理解,Profiler 中的數字表示 Unity 向系統索要的內存值,而系統則會根據當前的內存情況、內存管理策略來進行分配,不同的硬體採取的策略是不同的(比如是否保留緩存,何時換頁,內存回收的頻率等等)。

PSS 就是獲取當前的系統內存分配信息,這並不代表 app 的真實內存需求。

另外,還關乎 PSS 獲取演算法的具體實現,比如有些硬體不把顯存計算在內,有些會計算等等。

關於PSS和Profiler之間的數值關係,我們認為確實是存在聯繫的,但該聯繫在不同的硬體上是不同的,且需要由硬體廠商來提供,這也是我們僅僅把 PSS 作為參考,把 Profiler 作為關注點的原因所在。

圖形渲染

Q4:當關閉預渲染GI時會出現IndirectResolution,這個參數有什麼用,為什麼調大了以後會大大增加渲染時間,但是烘培出來沒有啥效果。

簡單來說,該值主要控制的是GI的烘焙密度,數值越大,表示每個單位距離內的texel越多,即烘焙得越精緻,自然烘焙的時間也越長。該值並不需要越大越好,場景越小,建議該值越低。該值為1時,對於多數場景,其烘焙效果已經足夠了,升高該值,其效果也不會有明顯提升。

開發者也可以參考Unity官方的說明文檔:

Unity - Manual: Lighting Window

運行性能

Q5:如何在移動設備上,對Bloom和全屏抗鋸齒進行優化?Unity標準資源裡面自帶的效率比較低(已經嘗試過Bloom(Optimized))。

建議使用Asset Store上適合移動端的Bloom Shader插件,比如FxPro: Bloom&DOF和BloomPro等。

對於AA,目前在移動設備上並沒有特別優化的方法,僅能建議在低端設備上關閉AA功能,而在高端設備上可嘗試開啟較低倍數(2x)的MSAA。

推薦閱讀:

我想開發一個APP,現在有React Native 和 API Cloud 兩個框架,我該如何選擇?
不越獄,直接跳過 App Store 安裝軟體是什麼原理?
某熊周刊系列:一周推薦外文技術資料(1.4)
一個普通而技能全面的互聯網工作者,選擇 Mac 還是 Windows PC?
前端工程師想入手ios開發,從react native入手合適么?

TAG:Unity游戏引擎 | 移动开发 | 性能优化 |