TMP耗時較高的優(yōu)化問題

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)步的你加入,也許你的方法恰能解別人的燃眉之急;而他山之“石”,也能攻你之“玉”。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容