天天看點

技術分享連載(二十四)資源管理性能優化資源管理性能優化資源管理

Q1:字型作為多個資源的依賴包,會在遊戲中被加載多次。我們現在有個問題,AssetBundle A資源依賴于這個字型,加載A的時候加載了一份字型,然後B資源也依賴這字型,而後加載B的時候我們沒有去重複加載字型,這時候發現B資源上出現了字型丢失的現象。

請問加載資源的時候,Unity會自動去識别記憶體裡是否有它的資源依賴包嗎?如果有的話,為什麼B加載的時候找不到已經存在記憶體中的字型?這裡需要手動去做些什麼處理嗎?

同時我發現依賴包資源如果進行了bundle.m_AssetBundle.Unload(false)以後,其他依賴于這個包的資源就引用不到了。我們流程上對于每個讀進來的AssetBundle,都會加載完後馬上進行Unload(false),請問如果是依賴包的話,是不是不能對其進行這步操作?

Unity引擎是會自動根據依賴關系去搜尋依賴的資源的,但需要注意的是,依賴的AssetBundle檔案必須存在。也就是說,依賴關系包如果後續還會使用的話,是不應該被Unload的,否則後續AssetBundle加載上來後,被依賴的資源是無法找到的。對于Unity 5.3之前的版本,出于記憶體的考慮,開發團隊可以通過CreateFromFile或LoadFromCacheorDownload來加載AssetBundle,既可以保留AssetBundle之間的依賴關系,同時又不會産生Webstream。 開發團隊可以參考你應該了解的AssetBundle管理機制,進一步了解相關API。

Q2: 我在用Profiler真機檢視iPhone App時,發現第一次打開某些UI時,Font.CacheFontForText占用時間超過2s,這塊主要是由什麼影響的?若iPhone5在這個接口消耗2s多,是不是問題很大?這個消耗和已經生成的RenderTexture的大小有關嗎?

Font.CacheFontForText主要是指生成動态字型Font Texture的開銷, 一次性打開UI界面中的文字越多,其開銷越大。如果該項占用時間超過2s,那麼确實是挺大的,這個消耗也與已經生成的Font Texture有關系。簡單來說,它主要是看目前Font Texture中是否有地方可以容下接下來的文字,如果容不下才會進行一步擴大Font Texture,進而造成了性能開銷。

Q3:SkinnedMeshRenderer.BakeMesh這個函數一般是什麼時候調用呢?在Instantiate後調用麼?

SkinnedMeshRenderer.BakeMesh 的作用在于:将一個蒙皮動畫的某個時間點上的動作,Bake成一個不帶蒙皮的Mesh,進而可以通過自定義的采樣間隔,将一段動畫轉成一組Mesh序列幀。而後在播放動畫時隻需選擇最近的采樣點(即一個Mesh)進行指派即可,進而省去了骨骼更新與蒙皮計算的時間。 該方法的優點是用記憶體換計算時間,在場景中大量出現同一個帶動畫的模型時,效果會非常明顯。該方法的缺點是記憶體的占用極大地受到模型頂點數、動畫總時長及采樣間隔的限制。是以,該方法隻适用于頂點數較少,且動畫總時長較短的模型。同時,Bake的時間較長,是以需要在加載場景時完成。 比較經典的适用場景為MOBA遊戲中的小兵。

Q4:我用Profiler.BeginSample統計到的資料與直接看Memory下的不一樣,前者比後者的資料更大,這是為何? 用Profiler的API擷取到的這一幀的記憶體消耗是85.6MB,而堆記憶體中顯示的是62.9MB,這怎麼了解?

Profiler.BeginSample

技術分享連載(二十四)資源管理性能優化資源管理性能優化資源管理

Profiler中資料

技術分享連載(二十四)資源管理性能優化資源管理性能優化資源管理
這種情況确實也是經常會遇到的。一幀中配置設定如此高的記憶體是會觸發GC.Collect的,而Mono中顯示的數值則是GC之後的Mono記憶體數值。

Q5:将Shader獨立打包,如果我在啟動遊戲的時候加載一次,那麼之後切換場景是不是就不用每次都加載了?

确切地說,要達到後續Shader都不出現加載開銷,需要滿足以下兩個條件: (1)包含Shader的AssetBundle檔案常駐記憶體; (2)Shader已經全Load加載好; 隻要滿足這兩個條件,後續加載好的GameObject,但凡依賴于這些Shader的,都會直接拿來進行使用,而不會再有加載和解析開銷。

原文出處:侑虎科技

轉載請與作者聯系,同時請務必标明文章原始出處和原文連結及本聲明。