http://blog.csdn.net/kaitiren/article/details/45071997
javascript
此總結由本身經驗及網上收集整理優化內容 包括:
.代碼方面;
.函數使用方面;
.ui注意方面;
.數學運算方面;
.內存方面;
.垃圾回收方面 等等...
本着相互交流 共同進步的原則
html
U3D開發性能優化筆記:
java
.NGUI: Atlas優化;ios
.poolmanager使用;程序員
.控制同屏drawcall次數;
算法
.SHADER優化頂點和運算;數組
.合批與動態剔除;緩存
.邏輯部分優化;(如看到不到的物件不要作公告板位置運算,不要播放animation)
性能優化
.物理幀UPDATE下降;服務器
.關閉垂直同步,下降圖片採樣,聲音預加載 方案 等等 。。;
.模型骨骼不要超過32根;
.貼圖不要太大,建議512 *512 如下;
.少用 CUTOFF和 aplha混合;
.3D遊戲效率基本原則就是費內存省CPU 和GPU;
.NGUI ANIMATION ANIMTOR 碰撞檢測 特效 渲染 這些都是性能消耗的大頭;
.Occlusion Culling使用;
.只用一個mesh renderer, 少用多materials, 最多3個;
.每一個角色儘可能使用一個 Skinned Mesh Renderer;
.面數問題每一個模型不要超過300~1500;
.模型儘可能不要分開, 若是多個模塊, 會屢次調用dc;
.通常角色應該沒有 IK 結點.
.儘可能不用像素光(pixels Lights).
.不用 軟陰影(soft shadow), 或者不用陰影(No Shadows)
.燈光能不用就不用, 陰影能夠用面來代替.
.少用實時燈光, 儘可能使用lightmap(強大的Unity內置了一個強大的光照圖烘焙工具Beast,這個東東是Autodesk公司的產品);
.transform和OnGUI (運算上的優化遠比不上 繪製效率上的優化,少個dc可能就比得上這些了)
.少用transform, 多用 myCachedTransform.
.動態物體的相關優化
優化主要分爲兩個方向,一個是資源相關優化和引擎相關的優化。資源相關的優化,大概分爲動態物體、靜態物體、紋理數據、音頻數據、程序包數據。對於動態物體好比NPC、怪物等,須要對面片數量的控制,大概在300到2000面。1500面就能夠體現人物細節,但若是是人物比較多,可能要下降面數,不要低於300。另外,一方面是控制Skinned Mesh Renderer的數量;另外一方面是控制材質數量在1到3種。人物最好用小於30根骨骼,若是你用的骨骼越多,耗費的CPU就更多,因此在移動平臺上儘可能少於30根。如今咱們看其餘動態物體,利用Dynamic Batching進行合批。這個下雨特效並非系統作的,是包含不少雨點的網格進行重複拷貝,而後錯亂移動實現的。每個雨點並非一個粒子,這樣能減小不少CPU的消耗,每個總體網格都會有一個頂點的控制,經過控制頂點數量,對系統實現雨點效果來講,這是一個至關省時省力的方法。
.靜態物體的相關優化
下面咱們來看靜態物體,靜態物體也是要控制面數和頂點數,頂點數少於500個。static是不會進行移動縮放、旋轉的,把它標記爲static,固然他們的材質是同樣的。不要添加animation組建,對於靜態物體來講,這個組件毫無心義,能把他丟掉就丟掉,由於這對CPU的消耗是很是客觀的。
.音頻程序的優化
關於音頻時間的播放,好比背景音樂,建議使用MP3壓縮格式,好比音效,要求數據儘快加載,這些數據比較小就能夠,使用WAV和AIF未壓縮音頻格式。關於程序包的優化,不少開發者會埋怨說打出來的包太大,如今介紹減小程序包的方法,首先使用壓縮格式的紋理,以顯卡的壓縮格式保存,使用壓縮網格和動畫數據。網格壓縮是先採用量化處理,固然這個壓縮是保證在包裏面的數據小,但運行時佔用的內存沒有減小,由於咱們並無把頂點刪除,可是對動畫數據來講,動畫數據通過壓縮處理後下降,能夠減小遊戲列層。
.代碼儘可能不要使用System.xml,咱們建議使用Mono.xml。啓用Stripping來減小庫的大小,使用剝離方式。
.引擎相關優化和物理相關優化
下來是引擎相關的優化,例如光照設置、相繼設置、粒子特效、物理特效等。那拿光照設置來講,光源所有的實時光照這是很恐怖的,每一次實施光照表明着每一次使用消耗,怎麼優化?有人使用LightMapping來製做靜態場景,他的好處是不須要用多張實施光照,而給場景很好的光照效果。有人使用Light Probes代替實時光照,好處是徹底不用怎麼消耗,並且運做性能也很是高。在有些時候使用Light Probes代替光照,他能跟場景很好的融合,在一個角落裏,這個任務會被陰影打得暗一些。若是說場景中確實須要一些實時光源,那麼確定是須要作過優化設置的實時光源,控制important的光源個數。若是說光源有些地方產生了交叉光,這個時候你能夠經過設置Pxel Light,控制每個光源都只接受一個動態光照,數目大概是1—2個。對於關閉光源的實時陰影,並非全部平臺都支持實時陰影,消耗也很是大,不建議你們使用。關於相機方面的設置,平面越近,渲染越少。咱們更建議使用分層,好比遠處的建築,對於建築物的裁減平面遠一些,若是是花草,就可使用平面就近一些。如今看一下粒子特效,粒子也是遊戲中須要優化的東西,建議屏幕中最大的粒子數不要超過200,同時每一個發射器發射的最大粒子數不要超過50。粒子尺寸也要儘量小,最終在屏幕有多少像素。他們中間的像素可能會被渲染不少次,至少四五次,這時發現粒子系統僅像素就填充了更多屏幕,這時候對遊戲來講很是耗費,對遊戲的其餘功能性能也有所影響。另一方面,對於很是小的粒子,儘可能不要開啓粒子碰撞功能。
.物理相關優化,物理儘量使用Sphere Coillider、Box Coillider等,儘可能避免使用Meh Colllider等。渲染設置,避免使用Alpha Test,由於很是耗時,性價比很低。關於Sttic Batching,對靜態物體進行Batch,對幾何數據的大小沒有限制。物體被合併後會帶來一些內存消耗,好比說有控制網格的物體,用Batch會合併成大物體。Dynamic Batching目前僅支持小於900頂點的網格物體。如何理解900呢,其實就至關於900個頂點數據大小的物體,若是說使用Position、Normal和UV三種屬性,那麼你只能Batch300個頂點。總體縮放的物體不能被Batch,除非他們的縮放值相同。以前有一個客戶作特效,使用Batch機制把面片合併,最終讓全部面片共享一個紋理,這時候發現這些面片沒有被Batch出來,致使運行遊戲時大概放三個技能就10多個招套。對於非總體用戶體,他們的Batch是須要很好利用到。
.紋理合並優化
如今來看紋理合並,紋理合並就是爲了特到Batch數量,合併物體首先須要合併工具,還要修改使用紋理的網格的UV,使他們使用紋理。合併紋理主要是參照Batch,提升渲染性能。但在合併材質後須要注意的是腳本訪問Renderer被拷貝。/*安擋剔除,建議使用PVS技術。建議你們使用自定義shader,例如高光效果,高光效果可能不須要作一些入射線的檢測,只是簡單把他的值放大也能夠模擬高光效果,從而減小一些消耗。
另一個是用profiler,經過他給的數據進行鍼對性的優化。以上是跟你們介紹優化的內容,如何做出良好優化,必定要作好良好的規劃,到後期就不會很麻煩,若是規劃沒有作好有可能會給程序帶來很大壓力,結果可能很不樂觀。*/最後,要不斷實驗不斷總結才能達到本身滿意的效果。
.下降Drawcal的話,有以下兩點小建議
(1)不要用Unity自帶UI或者iGUI, 用NUI 或者EZ GUI
(2)建立好的GameObject不用了就最好及時 刪除 / 設置active爲false/移出屏幕 。 這幾種方法均可以去掉該物體致使增長的Drawcall.
最近一段時間一直在作Unity 在IOS設備上的資源優化,結合Unity的官方文檔以及本身遇到的實際問題,我把本身認爲一些重要的信息羅列在下面,並儘量對將其量化,以方便更多須要作優化的朋友。
1、 角色
每一個角色儘可能使用一個 Skinned Mesh Renderer
這是由於當角色僅有一個 Skinned Mesh Renderer 時, Unity 會 使用可見性裁剪和包圍體更新的方法來優化角色的運動,而這種優化只有在角色僅含有一個 Skinned Mesh Renderer 時纔會啓動。
角色 Material 數量
2-3 個
骨骼數量
小於 30 個
面片數量
300-1500
通常角色應該沒有 IK 結點
這是由於角色的動做大多數都是事先設定好的,並不須要通過 IK 操做來進行實時計算( Rogdoll 除外),因此在模型導入時,不要將 IK 結點一塊兒導入。
2、 靜態實體
不要附加 Animation Component
在靜態實體上附加 Animation 部件雖然對結果沒有影響,但卻會增長必定的 CPU 開銷來調用這一組件,因此儘可能去掉該組件。
網格頂點數
小於 500
UV 值範圍儘可能不要超過( 0, 1 )區間
儘可能保證 UV 值不越界,這對於未來的紋理拼合優化頗有幫助。
3、 地形
地形的分辨率大小
長寬均儘可能小於 257 。這是由於地形太大,會形成大量頂點數據,給你的內存帶寬形成必定的影響,在目前的 ios 設備中,內存帶寬是很是有限的,須要儘可能節省。同時,若是用 Unity 自帶的地形,必定也要使用 Occlusion Culling ,由於 Unity 的刷地形工具雖然方便,但倒是 framekiller ,刷過以後,你會發現 drawcall 增長的很是多。
混合紋理數量
不要超過 4 。地形的混合操做是很耗時的,應該儘可能避免。能合併的紋理儘可能合併。
4、 紋理
紋理格式
建議 png 或 tga 。不用轉成 ios 硬件支持的 PVRTC 格式,由於 Unity 在發佈時會幫你自動轉的。
紋理尺寸
長寬小於 1024 。同時應該儘量地小,夠用就好,以保證紋理對內存帶寬的影響達到最小。
支持 Mipmap
建議生成 Mipmap 。雖然這種作法會增長一些應用程序的大小,但在遊戲運行時,系統會根據需求應用 Mipmap 來渲染,從而減小內存帶寬。
檢查 Alpha 值
若是紋理的 alpha 通道均爲 1 ,則用 RGB 的 24 位紋理來代替 RGBA 的 32 位紋理。(聽說 Unity 內部會進行自動檢測)
5、 光源
光源「 Important 」個數
建議 1 個,通常爲方向光。「 Important 」個數應該越小越少。個數越多, drawcall 越多。
Pixel Light 數目
1-2 個。
6、 粒子特效
屏幕上的最大粒子數
建議小於 200 個粒子。
每一個粒子發射器發射的最大粒子數
建議不超過 50 個。
粒子大小
若是能夠的話,粒子的 size 應該儘量地小。由於 Unity 的粒子系統的 shader 不管是 alpha test 仍是 alpha blending 都是一筆不小的開銷。同時,對於很是小的粒子,建議粒子紋理去掉 alpha 通道。
儘可能不要開啓粒子的碰撞功能。
很是耗時。
7、 音頻
遊戲中播放時間較長的音樂(如背景音樂)
使用 .ogg 或 .mp3 的壓縮格式。
較短音樂(如槍聲)
使用 .wav 和 .aif 的未壓縮音頻格式。
8、 相機
裁剪平面
將遠平面設置成合適的距離。遠平面過大會將一些沒必要要的物體加入渲染,下降效率。
根據不一樣的物體設置不一樣的遠裁剪平面
Unity 提供了能夠根據不一樣的 layer 來設置不一樣的 view distance ,因此咱們能夠實現將物體進行分層,大物體層設置的可視距離大些,而小物體層能夠設置地小些,另外,一些開銷比較大的實體(如粒子系統)能夠設置得更小些等等。
9、 碰撞
儘可能不用 MeshCollider
若是能夠的話,儘可能不用 MeshCollider ,以節省沒必要要的開銷。若是不能避免的話,儘可能用減小 Mesh 的面片數,或用較少面片的代理體來代替。
10、 其餘
Drawcall
儘量地減小 Drawcall 的數量。
iOS 設備上建議不超過 100 。
減小的方法主要有以下幾種: Frustum Culling , Occlusion Culling , Texture Packing 。
Frustum Culling 是 Unity 內建的,咱們須要作的就是尋求一個合適的遠裁剪平面; Occlusion Culling ,遮擋剔除, Unity 內嵌了 Umbra ,一個很是好 OC 庫。但 Occlusion Culling 也並非放之四海而皆準的,有時候進行 OC 反而比不進行還要慢,建議在OC 以前先肯定本身的場景是否適合利用 OC 來優化;
Texture Packing ,或者叫 Texture Atlasing ,是將同種 shader 的紋理進行拼合,根據 Unity 的 static batching 的特性來減小draw call 。建議使用,但也有弊端,那就是必定要將場景中距離相近的實體紋理進行拼合,不然,拼合後極可能會增長每幀渲染所需的紋理大小,加大內存帶寬的負擔。
這也就是爲何會出現「 DrawCall 降了,渲染速度也變慢了」的緣由。
非運動物體儘可能打上 Static 標籤
Unity 在運行時會對 static 物體進行自動優化處理,因此應該儘量將非運行實體勾上 static 標籤。
場景中儘量地使用 prefab
儘量地使用 prefab 的實例化物體,以下降內存帶寬的負擔。檢查實體的 PrefabType ,儘可能將其變成 PrefabInstance ,而不是ModelPrefabInstance 。
來自其餘開發者的筆記:
總的來講,Unity沒有啥天坑。只要肯研究,後期都能改進,也都不會影響到上線。
小坑太多,說不完。Unity上手容易坑太多,基本事件機制,生存週期,場景和資源管理,mono虛擬機的gc機制都是坑。
要說的話,真正影響到架構的是(排序)
1. 是否要用lua
2. (對於需操做的遊戲)客戶端遊戲如何作戰鬥驗證
公司的話,推薦:
參加Unity年會
購買Unity的官方支持問答平臺,人有源代碼,還能找總部
下面列舉小坑吧。不建議都繞開,畢竟沒有那麼多時間作前期調研的。
對應版本Unity4.x
1. 客戶端程序層面
總的來講C#超級給力的,不過別玩脫了
1) mono虛擬機gc
Unity的mono虛擬機使用不分代的gc算法,臨時對象積攢起來,致使重量級GC遊戲頻繁卡頓。
Unity官方:認真review每幀20B以上,以及一次2K以上的GC Alloc的行爲。傳聞:Unity5會改進。
評價:請像C++同樣精確瞭解各類行爲的gc,foreach 都不要隨便用。嚴重,但遊戲是能夠卡巴卡巴上線的。後期一位核心開發人員修2~3周。
2) 蘋果aot編譯問題:模板問題
mono在蘋果上採用aot將C#編譯爲靜態代碼。首先,依賴於動態代碼生成的複雜模板容易運行時崩潰;其次,mono會將客戶端生成一個庫。模板代碼實例化容易膨脹致使該庫超過40M而沒法連接。
實戰:碰到了改寫法吧。不過我本人是靜態類型檢查派的。
3) 少用coroutine
yield只支持try--finally,與異常體系兼容性極差;難以提供返回值;異步自己是非線性的,很難保證邏輯完備。
實戰:複雜異步邏輯用狀態機。不致命,多修bug也能抗過。
4) 自行處理配置數據序列化
嚴重影響配置讀取速度。C#自帶的xml序列化很慢,自帶的二進制序列化也不夠快。
實戰:打包配置考慮protobuf或者代碼生成器。中後期一週左右。
5) 反射
手機上jit狀況下,第一次反射一個類很慢。亂用足夠影響啓動速度。
6) 本地化
若是公司習慣於作海外市場,一開始就能夠考慮全套本地化方案。後期改須要一我的1~2個月工做量。
2 資源優化
Unity資源優化,一個靠譜的TA很重要。
1) 資源內存佔用
512內存機器能用的資源大概只有50~60M。需透徹研究貼圖。考慮換皮怪資源複用、UI的圖集合理化。沒有UI優化經驗的話,強烈建議一個核心開發死跟,像摳代碼優化同樣優化圖集總結經驗。這個後期很難收場。每一個粒子發射器佔用10K內存;有些項目在動畫上會有內存問題。
2) 關注資源包大小
最大的是貼圖和骨骼動畫。貼圖關注內存便可。骨骼動畫能夠佔到模型的一半大小,重作的話有各類優化方案。但超標後期也很難收場。
3) 依賴打包
Unity4.x和Unity5徹底不一樣。其中Unity4.x機制龐大繁雜容易錯,要有心理準備。扯一些要點:
* 必定要搞清其內存佔用和生存週期。要實測,特別容易跌眼鏡。
* 每一個API都有坑。我我的目前推薦壓縮模式、LoadFromCache,此時不能拆太碎。戰鬥前預加載。
* shader加載慢,應當放入依賴包
* bundle不能重名
4) 場景、drawcall、camera
場景面多了考慮動態batching。不一樣材質透明物體(例如粒子)穿插可能引發drawcall暴增。camera是重型對象,越少越好。
5) svn
資源選Text模式、顯式保存.meta,便於版本管理。資源分人或者鎖了改,規避衝突。
3 Unity
和Flash同樣容易學的3D編輯器
1 ) 事件機制
Unity事件機制很很差用。單個對象,Awake,Start,Enable調用時機至關複雜。Unity徹底不保證多個對象的事件執行順序,致使不少人繞開Start。不恰當的使用事件,很容易致使父子對象不在同一幀出現,畫面不乾淨。
Destroy操做是延遲的,對象會活到幀的結尾,而後一定銷燬。庫級設計時,必須考慮到這一點(例如對象池/動畫庫)。
2) 資源管理
只說Unity4.x。合理作法是依賴很卡的UnloadUnusedAssets、LoadScene清理無引用資源(另注意前者是異步的),或者Bundle.Unload(true),這些方案各有限制。試圖更細粒度手工清理的困難在於,並不存在系統性文檔解釋Unity資源的分類和生存週期,且Destroy操做很保守。例如,銷燬mesh時,並不會銷燬material、texture,更不會清理腳本資源。
此外,特定的普通操做會形成資源克隆。例如訪問Renderer.meterial,Animation.AddClip。
4 NGUI
久經驗證的掉鏈子王。新項目也能夠嚐嚐uGUI
1) panel重繪
widget改變後,所在panel須要生成多邊形,很慢,坑新人沒商量,注意合理分panel。panel中多邊形過多會爆(貌似是65535個頂點?)。
uGUI原理相同,就是c代碼比C#快很多。
2) panel渲染順序
搞清楚ui上放置3D物體咋辦,ui如何和特效混合排序。
3) 策劃/美術ui規範
潛規則不少。Anchor、動畫不可做用於同一個物體。widget必須是panel的子節點,否則他就會本身造panel,常常搞出亂子。再加上上面的panel規則等,要策劃美術折騰ui可費神了。
項目組自制UI編輯器天然是極好的,不過不必定必要。
4) 建立速度慢
因爲序列化字段多,NGUI對象建立可致使卡頓。多狀態對象不要靠隱藏-顯示,而要動態建立。尤爲是狀態中包含粒子發生器/Animation,這倆還有內存問題(10K一個)。
5) 與Unity事件機制強耦合
與Unity的事件機制強耦合,不完備,容易有bug。例如,panel繪製依賴於LateUpdate。coroutine中同時關閉舊界面,建立新界面,此時當前幀 LateUpdate 已過,表現爲有一幀畫面爲空白。
代碼部分的優化方案:
1
|
function Update() { DoSomeThing(); }
|
1
|
function Update() {
if
(Time.frameCount % 5 == 0) { DoSomeThing(); } }
|
1
2
|
function Start() { InvokeRepeating(
"DoSomeThing"
, 0.5, 1.0); }
CancelInvoke(
"你調用的方法"
); 中止InvokeRepeating
|
1
|
function Update() { var pos: Vector3 = transform.position; }
|
1
|
private
var pos: Vector3; function Update(){ pos = transform.position; }
|
1
|
function Update() {
if
(Time.frameCount % 50 == 0) { System.GC.Collect(); } }
|
U3D開發中的一些多餘組件問題:
在美術製做場景中,都會帶上 MeshCollider, Animation, Animator 等組件,包括材質中的shader部分也會使用mobile以外的diffuse,因此有一句話:「若是相信美術,母豬都會上樹」, 程序員們仍是本身動手來幹吧:
有提出改進需求的童鞋請留言;