1焰扳、美術(shù)篇
·美術(shù)規(guī)范:主要包括材質(zhì)數(shù)量倦零、模型三角面、紋理尺寸吨悍、粒子數(shù)量扫茅、動(dòng)畫幀頻。
a育瓜、對(duì)于導(dǎo)入unity的模型
?需要注意:若勾選上圖中”Read/Write Enabled”將會(huì)使該模型在內(nèi)存中存在一份拷貝葫隙,用于在腳本中對(duì)模型進(jìn)行修改。若該模型不會(huì)在腳本中進(jìn)行修改躏仇,則不勾選恋脚。Optimize Mesh 必須勾選,便于引擎底層對(duì)Mesh進(jìn)行優(yōu)化處理焰手。Normals & Tangents 中的Normals選項(xiàng)若設(shè)置為非Import項(xiàng)糟描,可以降低Memory,并減少ipa/apk包體容量书妻。
b船响、對(duì)于unity貼圖
Unity支持目前主流的各種圖片格式,包括PSD躲履,TGA见间,PNG,GIF工猜,BMP米诉,JPG,TIFF篷帅,PICT等史侣。若圖片尺寸不是2的指數(shù)汗销,其所占用內(nèi)存的大小略大于原始尺寸,并且GPU對(duì)其進(jìn)行讀取的速度也有可能會(huì)略微偏慢抵窒。若勾選Generate Mip Maps弛针,改貼圖所占用內(nèi)存會(huì)變大33%,但對(duì)整體性能有很大提升李皇。
c削茁、對(duì)于光照
移動(dòng)平臺(tái)推薦使用Baked或 Mixed,避免使用RealTime模式的光照掉房。Render Mode 不推薦使用Important茧跋。使用Baked模式時(shí),在菜單Window->Lighting的Object標(biāo)簽頁卓囚,可通過設(shè)置Scale In Lightmap的值瘾杭,以變更lightmap中有多少像素值用于該GameObject的光照計(jì)算。
d哪亿、對(duì)于音效
Unity支持主流的各種音樂格式粥烁,包括mp3,ogg蝇棉,wav讨阻,aif等。Load Type 中的Decompress On Load 選項(xiàng)不推薦用于大文件篡殷。大文件推薦使用 Compressed In Memory選項(xiàng)钝吮。Load In Background 如果勾選表示該音頻文件將在后臺(tái)加載,而不會(huì)造成主線程阻塞板辽。
2奇瘦、程序篇
a、邏輯架構(gòu)
設(shè)計(jì)時(shí)應(yīng)該遵循各功能模塊的獨(dú)立性和封裝性劲弦,并滿足即插即用耳标。比如,整個(gè)游戲邏輯可分為瓶您;場景模塊麻捻,角色模塊纲仍,UI模塊呀袱,網(wǎng)絡(luò)通信模塊,戰(zhàn)斗模塊等郑叠。模塊化設(shè)計(jì)不僅游戲邏輯樹簡單易懂夜赵,便于代碼審查,而且也有益于項(xiàng)目后期做性能優(yōu)化以及Bug檢查乡革。比如寇僧,調(diào)試Bug時(shí)摊腋,如果禁用某一個(gè)模塊,游戲正常運(yùn)行嘁傀,并且Bug不再出現(xiàn)兴蒸,則Bug由該模塊引擎的概率很高。同理细办,在做優(yōu)化處理是橙凳,如果禁用某一個(gè)模塊,發(fā)現(xiàn)CPU負(fù)載下降很多笑撞,則該模塊造成性能瓶頸的概率也很高岛啸。
b、腳本應(yīng)用
Unity的腳本使用托管機(jī)制茴肥,如果某腳本需要掛載到場景GameObject上坚踩,則該腳本需要繼承于MonoBehaviour。在菜單Edit-> Project Settings -> Script Execution下瓤狐,可更改各類腳本的執(zhí)行順序瞬铸。同時(shí),MonoBehaviour的執(zhí)行并非使用系統(tǒng)反射機(jī)制础锐,而是基于隊(duì)列存儲(chǔ)形式赴捞。
為了減少代碼托管開銷,在設(shè)計(jì)具體腳本時(shí)可以做一些優(yōu)化處理郁稍。比如赦政,有一個(gè)類ClassA,繼承于MonoBehaviour耀怜,在其Update函數(shù)里會(huì)執(zhí)行具體邏輯恢着。若該類有30個(gè)實(shí)例同時(shí)存在,則會(huì)存在30次托管開銷财破,遇到此類情況掰派,建議刪除ClassA中的Update函數(shù),轉(zhuǎn)而由自定義的UpdateEx函數(shù)替代。同時(shí),額外編寫一個(gè)ClassAManager類勒庄,其緩存一個(gè)ClassA的數(shù)組或者隊(duì)列锋拖,每次Update時(shí)遍歷該隊(duì)列,執(zhí)行每個(gè)實(shí)例的UpdateEx函數(shù)逗宁。(這個(gè)還真沒注意,以后要試試)
c、Asset管理
Unity中的Asset序列化支持二進(jìn)制趟薄、文本模式、混合模式三種典徊,具體可以在菜單Editor Settings –> Asset Serialization 下進(jìn)行設(shè)置杭煎,文本模式采用YAML格式恩够,增加可讀性。其中每一個(gè)資源文件都可以生成一個(gè)對(duì)應(yīng)的meta文件羡铲。(其實(shí)至今不知道這個(gè)序列化到底有什么好處蜂桶,有哪位讀者大大知道,指點(diǎn)一下小菜鳥吧R睬小J浩!)
在制作場景時(shí)贾费,建議把場景中的具體GameObject制作成Prefab钦购,而不是直接使用FBX格式,這樣便于引擎底層做資源管理褂萧。
Unity引擎中各種美術(shù)資源都可以編譯成AssetBundle押桃,包括紋理,模型导犹,Prefab唱凯,AnimationClip,AudioClip等谎痢。同時(shí)磕昼,AssetBundle支持壓縮與非壓縮格式,開發(fā)者可根據(jù)項(xiàng)目實(shí)際情況進(jìn)行設(shè)置节猿。
d票从、動(dòng)態(tài)更新
通常動(dòng)態(tài)更新包括美術(shù)資源與腳本的更新,美術(shù)資源建議使用AssetBundle滨嘱,腳本更新在Android平臺(tái)上可使用dll反射實(shí)現(xiàn)(僅限Anadroid平臺(tái))峰鄙,或者通過其它第三方非官方模式。(這部分目前還沒接觸到太雨,自己做的東西還沒用過這個(gè)吟榴,所以還在學(xué)習(xí)。囊扳。吩翻。。)
3锥咸、優(yōu)化篇
a狭瞎、圖形優(yōu)化 - Graphics
要實(shí)現(xiàn)圖形優(yōu)化,首先需要熟悉圖形學(xué)整個(gè)渲染管線流程她君,在此對(duì)其作簡要介紹:
應(yīng)用程序 (Application) -> 幾何體 (Geometry) -> 光柵化 (Rasterizer)脚作。
其中,幾何體階段具體包括:模型變換(Model & View Transform) -> 頂點(diǎn)著色(Vertex Shading) -> 投影變換(Projection) -> 裁切(Clipping) -> 屏幕映射(Screen Mapping)缔刹。
光柵化階段包括: 三角設(shè)置(Triangle Setup) -> 三角遍歷(Triangle Traversal) -> 像素作色(Pixel Shading) - > 合并(Merging)球涛。
進(jìn)行圖形優(yōu)化時(shí)校镐,首要步驟即為定位瓶頸在何處亿扁,CPU還是GPU?
如果渲染瓶頸發(fā)生在CPU鸟廓,通常對(duì)CPU進(jìn)行的圖形相關(guān)優(yōu)化主要涉及以下幾點(diǎn):
合并模型(美術(shù)人員手動(dòng)合并或者使用引擎的Batching技術(shù))
在合并模型時(shí)从祝,如果被合并的模型并未使用同一材質(zhì),那么該合并操作并不會(huì)提升性能引谜。同理牍陌,如果被合并的模型使用了多重材質(zhì),而并不共用貼圖员咽,合并操作也不會(huì)提升性能毒涧。
減少材質(zhì)的使用數(shù)量,盡量材質(zhì)共用
紋理拼接贝室,把多張小尺寸紋理拼接到同一張大尺寸紋理中
避免使用多重渲染契讲,比如反射,陰影滑频,像素光照等
動(dòng)畫優(yōu)化捡偏,包括減少骨骼數(shù)量,降低動(dòng)畫幀率等
CPU在圖形渲染中所承載的計(jì)算量沒有GPU那么高(前提是設(shè)備同時(shí)具備GPU和CPU)峡迷,所以在進(jìn)行圖形優(yōu)化時(shí)银伟,更多是針對(duì)GPU端,其具體包括:
模型對(duì)象
調(diào)整模型三角面是優(yōu)化美術(shù)資源的基本步驟绘搞,如果一個(gè)角色模型1500面能達(dá)到要求枣申,那為何要使用1600面呢。
當(dāng)場景中某些對(duì)象被標(biāo)記為Static時(shí)看杭,禁止在腳本中對(duì)其進(jìn)行位置忠藤,朝向,縮放更改楼雹,也就是如果需要更改一個(gè)對(duì)象的Transform屬性值模孩,則改對(duì)象不應(yīng)該被標(biāo)記為Static。
在設(shè)計(jì)模型時(shí)贮缅,盡量減少UV映射縫隙和硬邊的數(shù)量榨咐。
光照設(shè)計(jì)
在移動(dòng)設(shè)備上,盡量使用light map代替實(shí)時(shí)光照谴供,即便美術(shù)人員需要很炫的光照效果块茁,也可以預(yù)先由美術(shù)人員調(diào)節(jié)好實(shí)時(shí)光照效果后再進(jìn)行l(wèi)ight map烘焙。
在某些特定情況下,美術(shù)人員可能需要一些特定對(duì)象呈現(xiàn)出酷炫的效果数焊,建議使用Shader實(shí)現(xiàn)永淌,而非采用增加額外的光源。
減少像素光的數(shù)量(像素光是指的什么佩耳?求指點(diǎn))遂蛀,不僅可以降低CPU負(fù)載,也可以減少GPU消耗干厚。如果場景中某像素光照作用的兩個(gè)模型對(duì)象距離相隔較遠(yuǎn)李滴,建議不要對(duì)該模型對(duì)象進(jìn)行合并操作。
Shader性能
Unity引擎為開發(fā)者提供了大量的內(nèi)置Shader蛮瞄,基本滿足開發(fā)者的項(xiàng)目需求所坯。如果某些特殊效果需要自定義Shader,在編寫Shader程序時(shí)挂捅,需要注意一些具體細(xì)節(jié)芹助。
在Shader程序中減少使用或者不使用條件語句。GPU在硬件層面上與CPU有著極大差異籍凝,GPU以ALU(邏輯運(yùn)算單元)著稱周瞎,而CPU則存在著大量的控制器。
定義變量時(shí)饵蒂,應(yīng)考慮變量需要的精度位寬(Float 為32位声诸,half為16位,fixed為10位)退盯,比如定義的變量用于UV坐標(biāo)彼乌,則類型通常選擇half即可,如果選擇float渊迁,則會(huì)造成帶寬浪費(fèi)以及計(jì)算消耗增加慰照。
避免使用復(fù)雜的數(shù)學(xué)計(jì)算函數(shù),比如sin琉朽,tan毒租,pow,exp箱叁,log等墅垮,如果實(shí)在需要,建議單個(gè)Shader程序里該類復(fù)雜函數(shù)的使用次數(shù)不超過一次耕漱。
移動(dòng)平臺(tái)避免使用Alpha Test和Alpha Blend指令算色,如果不可避免,建議使用Alpha Blend螟够,而非Alpha Test灾梦。
紋理壓縮
壓縮紋理不僅可以節(jié)省內(nèi)存峡钓,同時(shí)也節(jié)省運(yùn)算帶寬。同時(shí)若河,建議3D模型貼圖都應(yīng)生成對(duì)應(yīng)的Mipmaps能岩,如果選擇生成Mipmaps,則該紋理對(duì)應(yīng)的內(nèi)存大小相對(duì)原先會(huì)變大33%左右牡肉,但如果不選擇生成Mipmaps捧灰,則在整體性能上會(huì)有很大損失淆九。
LOD使用
Unity中關(guān)于LOD的使用有LOD Group和Camera.layerCullDistances兩種方式统锤。其中LOD Group主要用于大型模型對(duì)象,而Camera.layerCullDistances主要用于碎片化的模型對(duì)象炭庙。
b饲窿、物理優(yōu)化
Unity引擎中物理計(jì)算更新在FixedUpdate中完成,根據(jù)具體的游戲項(xiàng)目焕蹄,如果游戲物理更新頻率不需要太高逾雄,可以在菜單Project Settings -> Time 下更改Fixed TimeStep的值。
使用物理碰撞體時(shí)腻脏,在滿足設(shè)計(jì)要求前提下鸦泳,建議使用Sphere Collider 或者 Box Collider代替Mesh Collider。Mesh Collider和wheel Collider其計(jì)算較為復(fù)雜永品,能避免使用則避免之做鹰。
被標(biāo)記為Static的碰撞體,禁止對(duì)其移動(dòng)位置鼎姐。
如果對(duì)象不需要Rigidbody組件钾麸,一律刪除。
在腳本中如果通過Physics.RaycastAll類似的接口獲取固定對(duì)象炕桨,緩存所得到的對(duì)象饭尝,禁止通過程序中每幀調(diào)用該類接口去獲取一個(gè)固定的對(duì)象。
c献宫、程序優(yōu)化
程序優(yōu)化的根本在于設(shè)計(jì)钥平,在于程序員在編寫程序時(shí)是否有細(xì)心思考。盡管Unity引擎本身由C++編寫姊途,但上層邏輯腳本基于Mono體系涉瘾,內(nèi)存管理使用GC機(jī)制。
GC機(jī)制在內(nèi)存管理存在實(shí)時(shí)性欠缺吭净,而Mono內(nèi)存基于內(nèi)存池睡汹,即Mono所申請內(nèi)存不會(huì)得到釋放(只有在內(nèi)存池中內(nèi)存不夠使用時(shí),Mono才會(huì)申請新的內(nèi)存)寂殉,只會(huì)返回內(nèi)存池囚巴。
基于以上機(jī)制限制,應(yīng)禁止頻繁申請內(nèi)存,盡量使用對(duì)象池管理對(duì)象彤叉,比如在Update函數(shù)里每幀都new 一個(gè)數(shù)組或者隊(duì)列庶柿,這樣極有可能造成GC還未回收先前的內(nèi)存,內(nèi)存池中內(nèi)存不足秽浇,又重復(fù)申請新的內(nèi)存浮庐,最終Mono內(nèi)存池越來越大,這是很多開發(fā)者都曾遇到的問題柬焕。
在Unity引擎層面审残,可以通過使用IL2CPP技術(shù),使腳本運(yùn)行速度更快斑举,同時(shí)搅轿,也可以在Script Call Optimization中設(shè)置忽略異常處理。針對(duì)具體腳本中負(fù)載瓶頸的定位富玷,建議多使用引擎的Profiler工具璧坟。
(ps:對(duì)于程序優(yōu)化這部分,基本不理解赎懦,還是基礎(chǔ)差雀鹃。。励两。黎茎。哪位能解釋一下,或者提供些相關(guān)資料伐蒋。謝謝)
d工三、文件優(yōu)化
如果要降低整體文件大小,首先得知道整個(gè)項(xiàng)目中每類資源文件具體大小先鱼。在Unity完成相關(guān)編譯后俭正,選擇Console -> Open Editor Log選項(xiàng),會(huì)得到如下圖所示的信息:
(ps焙畔,然而我在windows下打開log文件并沒有所有資源的大小描述掸读。。宏多。儿惫。糾正一下,在buliding的時(shí)候勾選這幾個(gè)就可以看見了伸但。)
其包括了具體各類資源的總大小肾请,開發(fā)者可按照文件大小建立優(yōu)化順序。其中更胖,具體在設(shè)計(jì)到腳本大小優(yōu)化時(shí)铛铁,根據(jù)項(xiàng)目組具體情況隔显,可以考慮選擇.Net 2.0 Subset,在iOS平臺(tái)也可使用Stripping方法饵逐。同時(shí)括眠,建議把Resources文件夾下不曾使用的資源刪除,需要使用的資源用AssetBundle代替倍权。Resources文件夾下文件太多會(huì)嚴(yán)重影響程序的啟動(dòng)時(shí)間掷豺。
文章摘自Unity官方微信,如有侵權(quán)請聯(lián)系本人下架薄声。