1)TMP耗時(shí)較高的優(yōu)化問(wèn)題
2)Unity重載Object后仇轻,如何判定物體是否為空
3)SRP Batch在添加unity_SpecCube后的問(wèn)題
4)堆內(nèi)存會(huì)持續(xù)上升,如何用UWA報(bào)告來(lái)分析
這是第326篇UWA技術(shù)知識(shí)分享的推送,精選了UWA社區(qū)的熱門(mén)話題臊泌,涵蓋了UWA問(wèn)答走哺、社區(qū)帖子等技術(shù)知識(shí)點(diǎn),助力大家更全面地掌握和學(xué)習(xí)卑吭。
TextMeshPro
Q:我們項(xiàng)目中UGUI的Canvas.SendWillRenderCanvases耗時(shí)高時(shí)經(jīng)逞康看到子節(jié)點(diǎn)TMP.GenerateText和TMP Parse Text耗時(shí)高《股停基本能定位到是角色對(duì)話字母跳字的時(shí)候挣菲,但是這是硬需求不好改。大佬們有沒(méi)有什么思路優(yōu)化一下掷邦?
A1:建議單獨(dú)給這塊開(kāi)Canvas白胀。
感謝歐月松@UWA問(wèn)答社區(qū)提供了回答
A2:角色對(duì)話時(shí)字幕上一個(gè)一個(gè)字蹦出來(lái)確實(shí)是比較常見(jiàn)的需求了,都是在一個(gè)Text組件里變化抚岗,而且字越多頂點(diǎn)數(shù)就越高或杠,耗時(shí)就比較可觀了。
我想到的一個(gè)思路還是改用靜態(tài)字體圖集宣蔚。
可參考:https://answer.uwa4d.com/question/63e30f3b0638540599016732
我之前也遇到這個(gè)問(wèn)題廷痘,所以做了下實(shí)驗(yàn):
在一個(gè)Text組件里用代碼控制連續(xù)輸出3000個(gè)中文字符集中各不相同的文字。在Profiler中觀察到:
1. 當(dāng)使用動(dòng)態(tài)字體時(shí)件已,每輸出一個(gè)字符都會(huì)在相應(yīng)的TMP動(dòng)態(tài)圖集紋理資源中新畫(huà)入一個(gè)字符笋额,在Unity 2021、TMP 3.0.6版本環(huán)境下篷扩,輸出到最后幾個(gè)字符時(shí)兄猩,Canvas.SendWillRenderCanvases耗時(shí)來(lái)到24ms左右。
2. 當(dāng)時(shí)在用靜態(tài)字體時(shí)鉴未,同樣的輸入方式和環(huán)境下枢冤,輸出到最后幾個(gè)字符時(shí),Canvas.SendWillRenderCanvases耗時(shí)降低到14ms左右铜秆。
在還有一些補(bǔ)充測(cè)試中淹真,耗時(shí)差距在真機(jī)上被進(jìn)一步放大;而且在一些較低的穩(wěn)定版本的Unity和TMP環(huán)境中實(shí)驗(yàn)結(jié)果也差不多连茧。這里就不一一列出來(lái)了核蘸∥∨矗總之,足以說(shuō)明使用靜態(tài)字體方案在耗時(shí)層面也是具有優(yōu)越性的客扎。
感謝Faust@UWA問(wèn)答社區(qū)提供了回答
Script
Q:Unity重載Object的 == 后祟峦,如何真的判定物體是否為空?
Unity中還找不到除了Try Catch外徙鱼,去區(qū)分Destroyed的物體和null的區(qū)別宅楞。一些資源追蹤操作,可以檢查Destroyed的物體袱吆,比如:獲得Destroyed物體的InstanceID厌衙,去識(shí)別到底具體出問(wèn)題的東西是什么。但是如果使用真null的物體調(diào)用這類接口绞绒,就會(huì)出現(xiàn)異常迅箩。
現(xiàn)在想找一個(gè),不觸發(fā)異常的干凈方法处铛,判定一個(gè)物體是被摧毀饲趋,還是真null。
A:簡(jiǎn)單的寫(xiě)法:
真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"。
其實(shí)是之前問(wèn)題的具體情況讨衣。在支持SRP Batch的Shader添加反射探針相關(guān)參數(shù)后:
如果把探針參數(shù)放在UnityPerDraw里面换棚,測(cè)試多種參數(shù)順序,都會(huì)出現(xiàn) "builtin property offset in cbuffer overlap other stages"問(wèn)題反镇;
但是放在UnityPerDraw外固蚤,又會(huì)出現(xiàn)提示要求把相關(guān)參數(shù)放進(jìn)里面去。
現(xiàn)在個(gè)人想法是歹茶,這些參數(shù)應(yīng)該放進(jìn)UnityPerDraw內(nèi)夕玩,但是具體順序有問(wèn)題。不知道有沒(méi)有成功植入測(cè)試的例子惊豺×敲希或者是對(duì)源碼有理解的兄弟可以給出一個(gè)可行的順序。
具體出現(xiàn)問(wèn)題的版本是2020.3.16f1尸昧。
項(xiàng)目現(xiàn)有問(wèn)題倒是通過(guò)將相關(guān)參數(shù)放在CBuffer外揩页,外加強(qiáng)制裁減變體,在測(cè)試到的環(huán)境中解決了烹俗。但是還是希望能夠解決這個(gè)深層次的坑爆侣。
A:今天也遇到這個(gè)問(wèn)題了萍程,看了下源碼,這些Built-in Feature累提,例如反射探針或者M(jìn)otion Vector,Unity是有一個(gè)Feature List來(lái)處理的磁浇,每當(dāng)你開(kāi)啟一個(gè)Feature斋陪,會(huì)在UnityPerDraw分配一個(gè)Block,然后你新加入的參數(shù)必須跟這個(gè)Block大小匹配置吓。
我的問(wèn)題是Motion Vector只用到了一個(gè)矩陣和一個(gè)float4无虚,但是Unity給分配的大小就是兩個(gè)矩陣+一個(gè)float4,所以如果要不影響合批衍锚,就得這么聲明友题。
你的情況感覺(jué)可以添加到probeVolume這個(gè)Feature的Block里,Catlike教程里也有提過(guò)戴质,測(cè)了下順序不要緊度宦,大小一致就行,3個(gè)float4和一個(gè)矩陣告匠。
感謝xltqM7stGjuG@UWA問(wèn)答社區(qū)提供了回答
Memory
Q:大佬們問(wèn)一下戈抄,我們項(xiàng)目的堆內(nèi)存會(huì)持續(xù)上升到400多MB,這個(gè)值太高了后专,而UWA報(bào)告中無(wú)論是平均分配值乘以幀數(shù)還是泄露分析中的駐留量雖然也很高划鸽,但是離400MB還有一些差值。到這里不知道怎么繼續(xù)分析了戚哎,有沒(méi)有好的建議裸诽?
A:2022年底幫一個(gè)項(xiàng)目解決了內(nèi)存一直漲的問(wèn)題,原因也是內(nèi)存碎片型凳。剛開(kāi)始以為是資源出的問(wèn)題丈冬,一直用Memory Profiler在定位問(wèn)題,只能看到Empty Heap Space一直在漲甘畅,到最后發(fā)現(xiàn)這個(gè)工具找不到原因殷蛇,但是大概確定了是內(nèi)存碎片太多。最后通過(guò)GC Allocated的變化定位了部分功能橄浓。
在這個(gè)過(guò)程中發(fā)現(xiàn)了Profiler里的波形和數(shù)值有時(shí)候是對(duì)不上的粒梦,明明有一個(gè)很大的波峰,但數(shù)據(jù)顯示根本不對(duì)荸实,這時(shí)通過(guò)這條波峰是定位不到功能代碼的匀们。
總結(jié)幾個(gè)容易出現(xiàn)碎片的關(guān)鍵字:
- byte[]
- MemoryStream
- ReadPixels
- DeflateStream
解決方法:大部分情況能用對(duì)象池解決。
感謝李偉@UWA問(wèn)答社區(qū)提供了回答
封面圖來(lái)源于網(wǎng)絡(luò)
今天的分享就到這里准给。當(dāng)然泄朴,生有涯而知無(wú)涯重抖。在漫漫的開(kāi)發(fā)周期中,您看到的這些問(wèn)題也許都只是冰山一角祖灰,我們?cè)缫言赨WA問(wèn)答網(wǎng)站上準(zhǔn)備了更多的技術(shù)話題等你一起來(lái)探索和分享钟沛。歡迎熱愛(ài)進(jìn)步的你加入,也許你的方法恰能解別人的燃眉之急局扶;而他山之“石”恨统,也能攻你之“玉”。