1)TMP耗時較高的優(yōu)化問題
2)Unity重載Object后,如何判定物體是否為空
3)SRP Batch在添加unity_SpecCube后的問題
4)堆內(nèi)存會持續(xù)上升,如何用UWA報告來分析
這是第326篇UWA技術(shù)知識分享的推送,精選了UWA社區(qū)的熱門話題,涵蓋了UWA問答、社區(qū)帖子等技術(shù)知識點,助力大家更全面地掌握和學(xué)習(xí)。
TextMeshPro
Q:我們項目中UGUI的Canvas.SendWillRenderCanvases耗時高時經(jīng)??吹阶庸?jié)點TMP.GenerateText和TMP Parse Text耗時高?;灸芏ㄎ坏绞墙巧珜υ捵帜柑值臅r候,但是這是硬需求不好改。大佬們有沒有什么思路優(yōu)化一下?
A1:建議單獨(dú)給這塊開Canvas。
感謝歐月松@UWA問答社區(qū)提供了回答
A2:角色對話時字幕上一個一個字蹦出來確實是比較常見的需求了,都是在一個Text組件里變化,而且字越多頂點數(shù)就越高,耗時就比較可觀了。
我想到的一個思路還是改用靜態(tài)字體圖集。
可參考:https://answer.uwa4d.com/question/63e30f3b0638540599016732
我之前也遇到這個問題,所以做了下實驗:
在一個Text組件里用代碼控制連續(xù)輸出3000個中文字符集中各不相同的文字。在Profiler中觀察到:
1. 當(dāng)使用動態(tài)字體時,每輸出一個字符都會在相應(yīng)的TMP動態(tài)圖集紋理資源中新畫入一個字符,在Unity 2021、TMP 3.0.6版本環(huán)境下,輸出到最后幾個字符時,Canvas.SendWillRenderCanvases耗時來到24ms左右。

2. 當(dāng)時在用靜態(tài)字體時,同樣的輸入方式和環(huán)境下,輸出到最后幾個字符時,Canvas.SendWillRenderCanvases耗時降低到14ms左右。

在還有一些補(bǔ)充測試中,耗時差距在真機(jī)上被進(jìn)一步放大;而且在一些較低的穩(wěn)定版本的Unity和TMP環(huán)境中實驗結(jié)果也差不多。這里就不一一列出來了??傊?,足以說明使用靜態(tài)字體方案在耗時層面也是具有優(yōu)越性的。
感謝Faust@UWA問答社區(qū)提供了回答
Script
Q:Unity重載Object的 == 后,如何真的判定物體是否為空?
Unity中還找不到除了Try Catch外,去區(qū)分Destroyed的物體和null的區(qū)別。一些資源追蹤操作,可以檢查Destroyed的物體,比如:獲得Destroyed物體的InstanceID,去識別到底具體出問題的東西是什么。但是如果使用真null的物體調(diào)用這類接口,就會出現(xiàn)異常。
現(xiàn)在想找一個,不觸發(fā)異常的干凈方法,判定一個物體是被摧毀,還是真null。
A:簡單的寫法:
真null的判斷:(go as object) == null;
如果不是真null,可以繼續(xù)判斷是不是Destroyed:(go as UnityEngine.Object) == null。
該回答由UWA提供,歡迎大家轉(zhuǎn)至社區(qū)交流
Rendering
Q:SRP Batch在添加unity_SpecCube相關(guān)參數(shù)后,出現(xiàn) "builtin property offset in cbuffer overlap other stages"。
其實是之前問題的具體情況。在支持SRP Batch的Shader添加反射探針相關(guān)參數(shù)后:
如果把探針參數(shù)放在UnityPerDraw里面,測試多種參數(shù)順序,都會出現(xiàn) "builtin property offset in cbuffer overlap other stages"問題;
但是放在UnityPerDraw外,又會出現(xiàn)提示要求把相關(guān)參數(shù)放進(jìn)里面去。
現(xiàn)在個人想法是,這些參數(shù)應(yīng)該放進(jìn)UnityPerDraw內(nèi),但是具體順序有問題。不知道有沒有成功植入測試的例子。或者是對源碼有理解的兄弟可以給出一個可行的順序。
具體出現(xiàn)問題的版本是2020.3.16f1。
項目現(xiàn)有問題倒是通過將相關(guān)參數(shù)放在CBuffer外,外加強(qiáng)制裁減變體,在測試到的環(huán)境中解決了。但是還是希望能夠解決這個深層次的坑。
A:今天也遇到這個問題了,看了下源碼,這些Built-in Feature,例如反射探針或者M(jìn)otion Vector,Unity是有一個Feature List來處理的,每當(dāng)你開啟一個Feature,會在UnityPerDraw分配一個Block,然后你新加入的參數(shù)必須跟這個Block大小匹配。
我的問題是Motion Vector只用到了一個矩陣和一個float4,但是Unity給分配的大小就是兩個矩陣+一個float4,所以如果要不影響合批,就得這么聲明。
你的情況感覺可以添加到probeVolume這個Feature的Block里,Catlike教程里也有提過,測了下順序不要緊,大小一致就行,3個float4和一個矩陣。

感謝xltqM7stGjuG@UWA問答社區(qū)提供了回答
Memory
Q:大佬們問一下,我們項目的堆內(nèi)存會持續(xù)上升到400多MB,這個值太高了,而UWA報告中無論是平均分配值乘以幀數(shù)還是泄露分析中的駐留量雖然也很高,但是離400MB還有一些差值。到這里不知道怎么繼續(xù)分析了,有沒有好的建議?

A:2022年底幫一個項目解決了內(nèi)存一直漲的問題,原因也是內(nèi)存碎片。剛開始以為是資源出的問題,一直用Memory Profiler在定位問題,只能看到Empty Heap Space一直在漲,到最后發(fā)現(xiàn)這個工具找不到原因,但是大概確定了是內(nèi)存碎片太多。最后通過GC Allocated的變化定位了部分功能。
在這個過程中發(fā)現(xiàn)了Profiler里的波形和數(shù)值有時候是對不上的,明明有一個很大的波峰,但數(shù)據(jù)顯示根本不對,這時通過這條波峰是定位不到功能代碼的。
總結(jié)幾個容易出現(xiàn)碎片的關(guān)鍵字:
- byte[]
- MemoryStream
- ReadPixels
- DeflateStream
解決方法:大部分情況能用對象池解決。
感謝李偉@UWA問答社區(qū)提供了回答
封面圖來源于網(wǎng)絡(luò)
今天的分享就到這里。當(dāng)然,生有涯而知無涯。在漫漫的開發(fā)周期中,您看到的這些問題也許都只是冰山一角,我們早已在UWA問答網(wǎng)站上準(zhǔn)備了更多的技術(shù)話題等你一起來探索和分享。歡迎熱愛進(jìn)步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之“石”,也能攻你之“玉”。