RectTransform-based Layouts
Layout組件性能開(kāi)銷比較大,因?yàn)槠渥釉卦谖恢煤痛笮“l(fā)生變化的時(shí)候會(huì)被設(shè)置為臟的。如果Layout中的元素?cái)?shù)量比較小并且元素比較小,并且Layout有比較簡(jiǎn)單的結(jié)構(gòu),那么可以使用基于RectTransform-based layout代替Layout。
通過(guò)分配RectTransform的錨點(diǎn),RectTransform的位置和大小可以基于它們的父節(jié)點(diǎn)。比如,一個(gè)簡(jiǎn)單的兩列布局可以通過(guò)下面兩個(gè)RectTransform實(shí)現(xiàn):
The left column’s anchors should be X: (0, 0.5) and Y: (0, 1)
The right column’s anchors should be X: (0.5, 1) and Y: (0, 1)
RectTransform的位置和尺寸計(jì)算由Transform系統(tǒng)自身驅(qū)動(dòng)。這比依賴Layout系統(tǒng)來(lái)計(jì)算性能更高。
禁用畫布
在顯示或隱藏UI中不連續(xù)的部分時(shí),常見(jiàn)的做法是在UI的根節(jié)點(diǎn)啟用或禁用GameObject,這樣可以確保UI組件不會(huì)受到輸入回調(diào)或Unity回調(diào)函數(shù)。
然而這樣做會(huì)導(dǎo)致Canvas丟失VBO數(shù)據(jù)。重新啟用畫布將進(jìn)行重建和批處理。如果這個(gè)操作很頻繁將導(dǎo)致CPU的幀率下降。
一個(gè)可行的辦法是將需要顯示隱藏的UI放到一個(gè)專用的畫布上,在禁用和啟用的時(shí)候,只禁用啟用這個(gè)畫布的組件。
這樣做UI的網(wǎng)格不會(huì)進(jìn)行重繪,這些數(shù)據(jù)將保留在內(nèi)存中,他們的原始批處理將被保留。
需要注意的是,這樣做并不會(huì)禁用被隱藏的UI上的任何MonoBehaviour,這些MonoBehaviour仍然會(huì)收到Unity的生命周期回調(diào),比如Update。
要避免這一問(wèn)題,以這種方式實(shí)現(xiàn)隱藏的UI上的MonoBehaviour不應(yīng)該直接實(shí)現(xiàn)Unity的生命周期回調(diào),而應(yīng)該去接收它們的UI根節(jié)點(diǎn)的自定義的“CallbackManager”的回調(diào)。當(dāng)UI被顯示和隱藏是,這個(gè)“CallbackManager”應(yīng)該收到通知,并決定是否傳播生命周期事件。
分配事件攝像機(jī)
如果Canvas的渲染模式為 World Space 或者 Screen Space - Camera 并且使用了Unity內(nèi)置的InputManager,一定要為其設(shè)置合適的EventManager/RenderCamera屬性。在腳本中,這兩個(gè)屬性都通過(guò)worldCamera屬性來(lái)設(shè)置。
如果沒(méi)有設(shè)置這個(gè)屬性,UI系統(tǒng)會(huì)通過(guò)在Tag為Main Camera的GameObject上尋找Camera組件來(lái)查找主相機(jī)。這一查找操作在每個(gè)World Space或Camera Space畫布上至少發(fā)生一次。由于 GameObject.FindWithTag的查找速度很慢,強(qiáng)烈建議在初始化時(shí)為World Space和Camera Space畫布設(shè)置相機(jī)。
在Overlay畫布上不存在這一問(wèn)題。