【厚積薄發】如何理解UGUI Atlas合批時的 Include in
這是第131篇UWA技術知識分享的推送。今天我們繼續為大家精選了若干和開發、優化相關的問題,建議閱讀時間10分鐘,認真讀完必有收穫。
UGUI
關於UGUI的合圖我有如下幾點疑惑:
1)UGUI的合圖是在什麼時候發生的?如果說合圖是在Editor下合出來的大圖,那麼打AssetBundle的時候似乎只打了圖集檔案與相關的小圖,並沒有看到有合成的大圖出現,那是不是Unity在執行時執行Late in binding時候進行了合併呢?
2、Include in Build到底是包含了什麼?我的理解是如果勾選了就會包含生成的大圖,如果不勾就不包含,那就又回到了問題1 ,如果不勾的話,那大圖是不是在執行時生成的呢?
3、小圖的大小會影響效能麼?首先小圖圖源肯定是會影響包體的大小。
基於問題1與問題2 ,如果是執行時生成的大圖,那麼在生成大圖的時候,I/O是否以位元組流的形式往空白大圖內進行寫入合併的?如果這樣,執行時生成大圖的瓶頸應該是原始檔的大小與格式吧?(假如圖集和圖源的壓縮格式不一致)
A:回答如下:
1、Unity合大圖的時機是根據設定來的。
如上圖,可以在打包的時候合,也可以編輯器執行的時候就合。Editor中合成的大圖是放在快取目錄裡:LibraryAtlasCache。
2、可以參考 About “Include in Build” behaviour
https://forum.unity.com/threads/about-include-in-build-behaviour.481433
我的理解是,勾選了Include in Build後,圖集資源會被打進App包體裡(不是AssetBundle包)。如果圖集是AssetBundle包管理的,最好不要勾選它,會造成資源雙份。至於哪些資源會雙份,需要實驗下看看。
3、小圖原始檔的大小不直接影響效能,因為Unity最終只用合併的大圖,小圖本身不會進入釋出的App或AssetBundle包中。但通常,小圖的大小和Sprite的設定會影響合併後的圖集,所以會對最終效能能產生間接作用。
針對Sprites Atlas在不同Sprite Packer Mode選項下打包,做了個實驗,結果分享下:
1、前三個選項(Disabled和兩個Legacy Sprite Packer)結果是一樣的:
打出的AssetBundle包裡沒有任何內容,估計這種情況下散圖都沒有,是完全載入不到資源的。
另:發現了疑似Unity的Bug,新建立的Atlas,和已經打包過的Atlas在禁用選項下,打包的結果不同。
2、後兩個結果相同:
生成AssetBundle包的時候,圖集就建立了
感謝Walker@UWA問答社群提供了回答
製作
Q:材質的Shader,或者GameObject元件的Monobehavior,在開發過程中可能會刪掉一個Shader的Property或者程式碼的序列化引數。這些引數被刪除後,材質或者GameObject Prefab檔案中,該引數的序列化資料並未被刪除。
比如下圖中名為TestGetDependency的元件。引數 testSubject已經從程式碼中刪除。
但是這個GameObject的Prefab檔案中,testSubject記錄仍然存在。
這樣會導致使用類似AssetDataBase.GetDependencies之類方法獲得資源依賴時,取得testSubject 引用的物體,導致打包時包入不需要的資源。用指令碼掃描SerializedObject的方式是可以清除這些引用的,但是這樣需要對應每一種類似情況單獨寫指令碼(當前只想到Shader對應材質,程式碼檔案對應Prefab),可能有遺漏或者處理不當。
所以我希望知道,有沒有一個Untiy原生的清洗方法,或者業界通用指令碼來處理這類序列化引用問題。
A:重新儲存下就好。
比較麻煩的是材質球,需要自己分析下然後清理serializedObject。
感謝錢康來@UWA問答社群提供了回答
渲染
Q:如下圖,在效能報告中,我們發現Camera.Render下CreateVBO的開銷較高,請問這個是如何引起的?
UWA:這本質上是你的網格重建導致的,多見於非UGUI的UI重建、Textmesh的重建等等,其重建時的CPU耗時主要受你的網格重建量大小影響,如果只是一幀其實問題不大,但如果是頻繁開銷,則需要特別注意了。
該回答由UWA提供
製作
Q:如圖,要實現一個勢力範圍的效果。應該用UI實現還是要做一個這樣的場景呢?現在我們的星圖是3D的Prefab,我打算在上面蓋一層黑色底圖,根據勢力範圍修改底圖顯示亮的區域,有沒有相關的外掛可以使用?要實現的話應該從哪方面入手?
A:可以建立一個RenderTexture,畫素點和地圖一一對應,通過修改RenderTexture顏色值,在Shader中進行對應的計算,達到效果。Unity 5.4以後,可以通過向Shader中傳遞陣列的方式實現效果。
感謝鄭驍@UWA問答社群提供了回答
記憶體管理
Q:不同記憶體的安卓與蘋果機型上(1G、2G、3G、4G...),遊戲記憶體的峰值一般最高多少能保證不閃退。
A:這裡有人會持續更新ios上的記憶體峰值,帖子下面還有人發了一個測試峰值的工具,用過還挺好用,大家可以參考。
https://stackoverflow.com/questions/5887248/ios-app-maximum-memory-budget.