這是摘自Unity官方文檔有關(guān)優(yōu)化的部分催什,原文鏈接:https://docs.unity3d.com/Manual/BestPracticeUnderstandingPerformanceInUnity.html
總共分為如下系列:
- 采樣分析
- 內(nèi)存部分
- 協(xié)程
- Asset審查
- 理解托管堆 【推薦閱讀】
5.1 上篇:原理,臨時分配內(nèi)存个少,集合和數(shù)組
5.2 下篇:閉包,裝箱屈暗,數(shù)組 - 字符串和文本
- 資源目錄
- 通用的優(yōu)化方案
- 一些特殊的優(yōu)化方案
真實項目中大部分錯誤都是無心之過——臨時的測試改動或者某個非常累的開發(fā)者不小心設(shè)置錯了資源導(dǎo)入設(shè)置略吨,造成資源出現(xiàn)大問題。
對于規(guī)模很大的項目奉瘤,需要加入對抗人為錯誤的首條防線。例如煮甥,寫幾行代碼確保沒有人可以給工程提交了一個4K的未壓縮紋理盗温。你可能覺得很意外,但是這是一個非常常見的錯誤成肘。一個4K的未壓縮紋理會占據(jù)超過60MB的內(nèi)存資源卖局。在比較低端的設(shè)備上,例如iPhone4S上双霍,超過180-200MB的內(nèi)存就比較危險了砚偶。如果錯誤地添加了這個問題,1/4~1/3的內(nèi)存就被占用了洒闸,也會造成非常難檢測的內(nèi)存溢出問題染坯。
雖然在5.3之后,可以用內(nèi)存剖析工具找到這個問題顷蟀,但是還是最好在一開始就防止類似這樣的問題發(fā)生酒请。
使用AssetPostprocessor
Unity編輯器中的AssetPostprocessor類可以用來確定Unity工程中的資源是否滿足標準骡技。當(dāng)資源被導(dǎo)入的時候鸣个,這個類會收到回調(diào)。使用這個類的方法只需要繼承布朦,自己實現(xiàn)多個OnPreprocess方法即可囤萤。重要的方法有:
- OnPreprocessTexture
- OnPreprocessModel
- OnPreprocessAnimation
- OnPreprocessAudio
具體可以參見AssetPostProcessor,可以知道更多的OnPreprocess方法是趴。
public class ReadOnlyModelPostprocessor : AssetPostprocessor
{
public void OnPreprocessModel()
{
ModelImporter modelImporter = (ModelImporter)assetImporter;
if(modelImporter.isReadable)
{
modelImporter.isReadable = false;
modelImporter.SaveAndReimport();
}
}
}
上面是應(yīng)用AssetPostprocessor的一個例子涛舍。
當(dāng)項目中導(dǎo)入模型的時候或者模型的導(dǎo)入設(shè)置被更改的時候,這個方法會被調(diào)用唆途。這個方法會檢測Read/Write屬性富雅,如果屬性為true掸驱,強制改成false,保存并且重新導(dǎo)入没佑。
記住毕贼,SaveAndReimport方法會導(dǎo)致這個代碼又被執(zhí)行一次,因為會強制將屬性改為false蛤奢,所以不會進入到無限循環(huán)鬼癣。
這個改動的原因可以參見模型部分。
常見的資源規(guī)則
紋理Texture
關(guān)閉read/write enabled的標志
Read/Write enabled標志導(dǎo)致Texture會在內(nèi)存中存在兩份資源:一份在GPU啤贩,一份在GPU尋址空間【因為在大部分平臺待秃,從GPU內(nèi)存讀取非常緩慢。從GPU內(nèi)存讀取紋理資源到臨時緩沖區(qū)非常不劃算】痹屹。在Unity中章郁,這個選項默認被關(guān)閉,但是有可能被意外開啟志衍。
Read/Write enabled屬性被打開只有在Shader外操作紋理數(shù)據(jù)才有意義(例如Texture.GetPixel和Texture.SetPixel等)所以應(yīng)當(dāng)盡可能避免開啟驱犹。
盡可能關(guān)閉Mipmaps
如果對象相對于Camera的Z深度不變,最好關(guān)閉mipmaps可以節(jié)省大概1/3的內(nèi)存足画。如果對象的Z深度值會變化雄驹,關(guān)閉mipmaps可能導(dǎo)致GPU的取樣效果比較差。
通常來講淹辞,UI紋理和在屏幕上是固定大小的紋理資源通過可以關(guān)閉掉mipmaps選項医舆。
壓縮所有的紋理
對于目標平臺使用合理的紋理壓縮格式可以節(jié)省內(nèi)存資源。
如果目標平臺的紋理壓縮格式設(shè)置的不合理象缀,Unity加載紋理資源之后會對紋理資源重新解壓蔬将,會消耗大量CPU時間和內(nèi)存資源。這對于Android設(shè)備很常見央星,通常是因為不同的芯片級支持不同的紋理格式霞怀,差異太大,難以統(tǒng)一莉给。
建立紋理限制條件
雖然這個很簡單毙石,但是通常很容易忘記重新調(diào)整紋理的大小,或者不小心改變了導(dǎo)入設(shè)置中的紋理大小颓遏。最好是通過代碼確定不同類型的紋理資源是否滿足了設(shè)定的規(guī)則徐矩。
模型Model
關(guān)閉Read/Write enabled的標志
Read/Write enabled標志對于模型而言和Texture中的道理相同。但是叁幢,對于模型而言滤灯,Unity對于這個選項默認開啟。
當(dāng)項目會在運行過程中通過代碼修改Mesh,或者Mesh被用來作為MeshCollider組件的基礎(chǔ)時鳞骤,Unity要求這個屬性必須開啟窒百。如果模型沒有用到MeshCollider中或者不需要通過代碼修改,將這個屬性改成false可以節(jié)省一半的內(nèi)存資源豫尽。
對于非Character類的模型關(guān)閉rigs
默認情況下贝咙,Unity會為非Character模型導(dǎo)入一個原生的rig。這樣會導(dǎo)致如果在運行過程中實例化這個模型拂募,Animator組件會被添加庭猩。如果這個模型不需要通過Animation系統(tǒng)控制動畫,就會增加額外的開銷陈症。因為所有處在活躍狀態(tài)下的Animator會在每幀被觸發(fā)蔼水。
對于不需要動畫的模型最好關(guān)閉這個屬性防止增加額外的Animator組件和場景中出現(xiàn)不需要的動畫效果。
對于有動畫效果的模型開啟Optimize Game Objects選項
Optimize Game Object選項對于有動畫的模型有非常大的性能影響录肯。當(dāng)這個選項被關(guān)閉之后趴腋,當(dāng)模型被實例化的時候,Unity會創(chuàng)建一個大的Transform層級用來映射模型的骨架結(jié)構(gòu)论咏。這個transform的Update開銷會非常大优炬,尤其是有其他的組件(如例子系統(tǒng)或者碰撞器)掛接在上面的時候。這個屬性同時也會影響Unity多線程處理蒙皮和骨骼動畫運算的能力厅贪。
如果某個模型骨架的一部分需要被暴露出來蠢护,如某個模型的雙手部分需要控制武器,那么這些部分可以列入Extra Transforms列表的白名單养涮。
更多的細節(jié)可以參見Unity教程的模型導(dǎo)入部分葵硕。Model Importer
盡可能使用Mesh壓縮
啟用網(wǎng)格壓縮之后,用來表示模型數(shù)據(jù)的不同頻道的浮點數(shù)的位數(shù)會減少贯吓。這樣雖然會引起精度的丟失懈凹,所以最終的效果需要被美術(shù)同學(xué)認可才能放入最終的工程中。
具體的浮點數(shù)的位數(shù)和壓縮等級之間的關(guān)系可以參見Scripting API的ModelImporterMeshCompression.
需要注意的是悄谐,不同的頻道可以使用不同的壓縮等級介评,所以在項目中可以選擇壓縮切線和法線而不壓縮UV和頂點位置。
注意:網(wǎng)格渲染的設(shè)置
當(dāng)向Prefab或者GameObject添加網(wǎng)格渲染器的時候爬舰,需要注意設(shè)置問題们陆。默認情況下,Unity會開啟Shadow casting and receiving洼专,Light Probe sampling棒掠,Reflecion Probe sampling和Motion Vector calculation孵构。
如果項目中不需要使用到上面的這些特性屁商,請用腳本確保上面的屬性被關(guān)閉。任何執(zhí)行添加MeshRender的運行代碼也需要確定是否開啟這些屬性。
對于2D游戲而言蜡镶,如果不小心向場景中加入的MeshRender中shadow選項未被關(guān)閉雾袱,會給渲染循環(huán)中加入額外的shadow pass過程,對于性能來講是浪費官还。
音頻
針對平臺選擇合適的壓縮選項
確保對于硬件設(shè)備選擇合適的壓縮格式芹橡。所有的iOS設(shè)備硬件支持MP3解碼,而很多Android設(shè)備原生支持Vorbis格式望伦。
而且林说,向Unity中導(dǎo)入未壓縮的音頻格式,Unity當(dāng)打包工程的時候會壓縮這些音頻文件屯伞。所以沒有必要導(dǎo)入壓縮的音頻文件腿箩,然后又解壓,這樣只會降低最后音頻的品質(zhì)劣摇。
將音頻強制改成單聲道
很少移動設(shè)備有立體揚聲器珠移。在移動設(shè)備的工程里,將導(dǎo)入的音頻強制改成單聲道可以節(jié)省一半的資源消耗末融。對于不需要有立體聲效果的音頻也是同樣處理钧惧,如UI聲效。
降低音頻碼率
當(dāng)然這個需要和負責(zé)音頻部分的同事進行溝通勾习,最大化降低音頻文件的碼率可以更進一步的減少內(nèi)存消耗和打包的工程大小浓瞪。
上篇:協(xié)程
下篇:理解托管堆...上
如果覺得文章對您有用,請點個贊唄巧婶!???