Unity3d常見性能優化技巧

轉自:http://unity3dhome.com/thread-790-1-1.html

 

優化的常規技巧

n 剖析你的遊戲。 不要花費時間來優化那些晦澀的代碼或者縮減圖形文件的大小,除非這是你遊戲的瓶頸。第一次剖析你的遊戲將會使你發現你遊戲的瓶頸。Apple's Shark是一個很好的用來剖析基於OpenGL的程序的工具。

n 再次剖析你的遊戲。 優化之後不要忘記再剖析一次你的遊戲,這樣可以檢查你所做的優化是否達到了預期的效果。當然,這樣做也可能會使你發現更多的瓶頸。

n 流程第一、性能第二。 花費時間來使你遊戲的創建儘可能地流暢。儘可能快地修正遊戲中的錯誤將會使你後期更容易優化你的遊戲。

n 在Scene View中測試場景。 這樣做將會使你清楚瞭解這個場景中的物體或者附加在物體上的腳本是否降低了遊戲性能。如果Scene View反應遲鈍,那麼有可能是圖形方面的原因,如果Scene View反應不遲鈍,那麼瓶頸可能出在腳本或者物理系統上。

n 禁用指定遊戲物體。 在play模式下,嘗試禁用並啓用遊戲物體來排查出遊戲慢的原因。



網格

n 如果可能的話,把相鄰的物體(網格)合併爲一個只有一個材質的物體(網格)。 比如,你的遊戲中包含一個桌子,上面有一堆東西,你完全可以在3D程序中將它們合併在一起(這可能也需要你將這些物體的紋理合併爲一個大的紋理集)。減少需要渲染的物體的數量可以極大地提高遊戲性能。

n 不要有不必要的網格。 如果你的遊戲場景中有一個人物,那麼他應該是一個網格。如果你有一個船,那麼它也應該只是一個網格。

n 每一個網格只用一種材質。

n 使用極少的面數的網格(比如500個多邊形以下)。

n 最好把你人物的三角面數量控制在1500-2000個之間。 這個數量可以說是遊戲質量和性能之間一個均衡值。如果你的模型有四邊形,那麼在導入模型的時候,引擎將會把每個四邊形變爲兩個三角形。



光照

n 像素光。 像素光可以讓你的遊戲看起來效果很牛逼,但是不要使用過多的像素光。在你的遊戲中可以使用質量管理器來調節像素光的數量來取得一個性能和質量的均衡點。

n 性能佔用順序:聚光燈>點光源>平行光。 一個好的點亮場景的方法就是先得到你想要的效果,然後看看哪些光更重要;在保持光效的前提下看看哪些光可以去掉。

n 點光源和聚光燈隻影響它們範圍內的網格。 如果一個網格處於點光源或者聚光燈的照射範圍之外,並且光源的attenuate開關是打開的,那麼這個網格將不會被光源所影響,這樣就可以節省性能開銷。這樣做理論上來講可以使用很多小的點光源而且依然能有一個好的性能,因爲這些光源隻影響一小部分物體。一個網格在有8個以上光源影響的時候,只響應前8個最亮的光源。



貼圖

n 在外觀不變的前提下,貼圖大小越小越好。 如果你的顯卡的顯存不夠大的話,你遊戲中的貼圖將會被轉存到系統內存中,在顯卡調用它們的時候再傳到顯卡中。對於比較新的電腦來說,內存和顯卡之間有足夠的帶寬來達到一個很好的性能;如果你很無恥地用了巨多的大圖片的話,在低顯存的電腦上運行你的遊戲的時候,你的遊戲必然會掛掉。倒是沒有必要在圖形編輯軟件中調整貼圖的大小。你可以在unity導入貼圖的時候進行調整。

n 不要使用低質量的圖片。 在小播放界面的遊戲中使用低質量的jpeg圖片或者低色彩的png圖片亦或是gif圖片沒什麼問題。在發佈遊戲的時候,引擎會自動壓縮這些圖片,多重壓縮和解壓將會降低圖片的質量,所以最好保持貼圖文件的分辨率爲原始分辨率。這樣就會減少多重壓縮和解壓所導致的圖片失真現象。


音頻

n 使用.ogg格式的壓縮音頻文件。 所有其他的音頻格式文件在發佈時將會被轉儲爲未壓縮音頻文件。

n 對於小音效使用未壓縮音頻文件。 Unity在運行過程中會解壓所有的ogg文件。它會把經常播放的音效轉儲爲WAV或者aiff格式的文件,這樣就可以不用cpu總是解壓這些文件了。比如快速的槍聲,腳步聲和其他一些連續播放又很短小的音效。



物理

n 每一個剛體都需要大量運算,所以剛體越少越好。 當角速度和移動速度降低到某個臨界值的時候,剛體將會進入休眠狀態。當剛體進入休眠狀態時,他們需要的運算量將會大量減少,但是會保留很少的一部分運算來隨時應對外部的作用力或者物體的碰撞。

n 多重碰撞相比一個接一個地碰撞將會花費更多的運算。 比如一個球去碰一堆球所需要的計算量會遠遠大於去一個一個地碰這些球所需要的計算量。



Shaders

n 多重效果的shader就比看起來樣式很單一的shader要更耗費資源。 同樣在一個擁有貼圖和光反射的物體上,使用VertexLit Diffuse shader無疑是最省資源的。


腳本

n 選擇適當的算法。 選擇一個正確的算法將會更容易進行優化。最好的算法不一定就是算法複雜度最低的算法。

n 儘量不要使用FixedUpdate()函數。 這種函數在每一個物體的每一個腳本中每秒調用50-100次。如果可以的話儘量把這個函數裏面的東西放在Update()函數中執行。

n 如果可能的話,在腳本無用的時候禁用它。 比如有一個敵人在數千米開外的位置,完全可以禁用它的AI腳本,直到需要的時候再啓用這個腳本。啓用和禁用物體的最好方法就是使用gameObject.SetActiveRecursively(false)函數,並且把物體的球碰撞和盒碰撞都置爲trigger。

n 如果不需要Update函數的時候就刪掉它。 在創建一個新腳本的時候,系統會自動加入一個空的Update函數,如果你不使用它的話就把它刪掉。

n 適當的時候使用物體引用。 如果調用一個物體需要走一個很彎的邏輯,比如someGameObject.transform.gameObject.rigidbody.transform.gameObject.rigidbody.transform,這樣就不如直接在腳本中聲明一個變量,把要調用的物體直接賦給這個變量。

n 儘量使用協同函數。 協同函數開銷很小,相比於一直在進行不必要調用的Update函數來說更好用。舉例來說,如果你有一個控制燈光漸明漸暗的腳本,你就完全可以使用協同函數來替代Update函數。這樣的話,在大多數時間燈光不變化的時候,系統的開銷會很小。如果這一過程是在Update函數中執行的話,Update函數會一直檢測是否需要執行漸變。

n 儘量不要使用搜索物體的函數。 比如GameObject.FindByTag()和 GameObject.GetComponent(),搜索組件的函數也一樣儘量少用。搜索就等於遍歷,搜索一次物體就要把所有物體都遍歷一遍,這個開銷我不說大家也應該都明白。尤其要注意,不要在Update()和FixedUpdate()中使用搜索函數,如果需要的話,最好在Start函數中使用變量來獲取一次,之後調用就直接用這個變量。

n 儘量不要使用SendMessage()函數或者類似的函數。 SendMessage()函數的執行速度至少比直接調用一個function慢100倍,隨着腳本和函數的增多,這個速度會更慢,所以如果能直接調用函數的話就直接調用。

n 關於JavaScript(Boo)中的動態類型。 在使用JavaScript時,聲明變量的儘量明確指定它的類型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章