- 使用GameObject.SetActive直接開關整個GameObject
- 開關GameObject上的Render
- 將GameObject移進/移出畫面
- 改變GameObject的Layer
- 改變GameObject的Scale, 設0為隱藏
對此我做了一個簡單的範例來測試這些方法的效能差異
測試專案: https://github.com/GooKu/Unity2017Test.git
測試碼: https://github.com/GooKu/Unity2017Test/blob/master/Assets/ShowHideTest/ShowHideTest.cs
測試scene: ShowHideTest.unity
環境資訊
CPU: i5-4460(3.2GHz)
VGA: AMD R7770-PMD1GD5
OS: Windows 10
Unity版本: 2017.1.0f3 Personal
Platform: PC Standalone
----------
此測試中使用的測試物件為裝有3個Sprite Render的GameObject物件, 其3個Sprite Render使用的是同一張128x128的JPG貼圖, 但用的是不同子sprite此測試物件的模型設計概念為:我們視覺上想控制顯示的物件單位, 常常是由許多render單位組成(可能是為動畫控制, avatar需求, 或其他因素), 因此使用一個GameObject乘載多個render的結構來做測試
擊點對應按鈕同時操作10000個測試物件的顯示/隱藏, 得到的結果如下
操作方法 \ 時間(ms) | 顯示 | 隱藏 | 隱藏後fps | |
GameObject.SetActive | 76 | 27 | 60 | |
Render.enabled | 22 | 22 | 60 | |
Move position | 9 | 9 | 60 | |
GameObject.layer | 19 | 19 | 25 | |
transform.localScale | 9 | 9 | 13 |
GameObject.SetActive: 效能開銷為最高, 尤其是在開啟GameObject時所花的時間是其他人的數倍
Render.enabled: 效能開銷其次, 開銷有部分為Dictionary的索引開銷, 但實在無法細分因此還是算在一起, 不過通常Dictionary的索引開銷是相對可以忽略的
GameObject.layer: 效能開銷接近但低於Render.enabled, 但值得一提的是, 在設到隱藏layer後, Profiler仍顯示有很高的Gfx.WaitForPresent開銷, 這個是CPU在等GPU的時間, 也應此隱藏後的fps仍不高
但照理來說, 沒有camera要畫隱藏layer時應該不會有這個開銷, 這有可能是Unity的bug?
transform.localScale: 雖然起停開銷和移位置一樣, 但隱藏後的fps和隱藏前幾乎一樣;
從Profiler來看, 既使scale 0 Camera.Render仍會對測試物件做處理
沒有留言:
張貼留言