![]()
時光流轉,深耕不輟。UWA知識型欄目《厚積薄發 | 技術分享》已悄然陪伴大家走過459個工作周。在這一年的技術征途里,我們依舊扎根真實的游戲開發場景,以問答社區的經驗沉淀為基石,又迎來了UWA AI技術的全新助力。
2025年的十大精選內容,既收錄了社區開發者們互助探討的智慧結晶,也融入了UWA AI基于海量知識沉淀的精準解答,每一篇分享都瞄準開發中的痛點卡點,為大家提供切實可行的破局思路。
回望這一年,是無數開發者的踴躍分享與積極互動,讓技術的價值持續傳遞;展望2026年,UWA問答社區與UWA AI問答將繼續并肩前行,以更專業的內容、更高效的解決方案,陪伴每一位開發者在技術深耕之路上穩步邁進!
UWA 社區主頁:community.uwa4d.com
From
問答社區
TOP1:如何讓GameObject銷毀時無論是否Active過,都調用OnDestroy?
請教一個問題,MonoBehaviour的OnDestroy方法,如果這個GameObject的實例化時就是隱藏的,銷毀時不會調用OnDestroy方法。我們項目有些核心邏輯是基于這個OnDestroy做的(時間太久遠,耦合太多邏輯不好改出去了)。有沒有什么辦法,可以讓這個GameObject銷毀時無論是否Active過,都調用OnDestroy。
A:要觸發OnDestroy,必須要觸發過Awake(Awake可以不明著寫出來),通常是被實例化或者第一次激活的時候觸發Awake,如果一直處于不激活的狀態,那么銷毀的時候不會自動觸發OnDestroy。所以可以在激活的父節點上主動SetActive一下:
![]()
A2:1. 一般一個Prefab本身是點亮的,大部分是里面的某些節點才會隱藏。如果是我說的這種情況,應該是在根Prefab摧毀的時候主動調用一次需要控制調用的子組件。
![]()
2. 如果你真的是根Prefab就隱藏的那更簡單了:
(1)做一個工具掃描所有Prefab檢查并且修改點亮情況;
(2)編輯器模式下加載完一個Prefab之后檢查是否點亮,如果沒有則打印Error。
A3:我們也遇到了這個,主要導致的問題自定義組件清理不掉Lua注冊過來的回調,導致返回登錄報錯。
我這邊解決思路是,在腳本反序列化之后,將自己注冊到UI根節點的管理腳本上,由這個管理腳本在Destroy時清理下面的子節點。Base腳本如下圖:
![]()
有幾個要點說明下:
1. 我們只處理了UI(其他地方基本不會出這問題),項目的用法上每個UI根節點有必掛的組件,這個組件一定會執行Awake;
2. 如果組件自身Awake走到了,就不需要額外的銷毀管理,需要從管理器中將自己移除;
3. 反序列化接口中有一堆限制,要小心處理,比如常用的接口只能在主線程執行,如果在子線程要跳過。還有Prefab打開的編輯狀態也有一些狀態取不到,我這邊直接忽略了(因為不常用)。
歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/67d390183d306f3e9d594e7a
From
UWA AI 問答
TOP2:Unity中可以禁用GC嗎?
Unity中可以禁用GC嗎?
A:在Unity中,可以禁用垃圾回收(GC),但需謹慎使用,并結合具體場景進行管理。
禁用GC的方法
Unity提供了通過腳本控制垃圾回收器行為的API:GarbageCollector.GCMode。
該API支持以下三種模式:
GarbageCollector.Mode.Enabled:默認模式,自動觸發GC。
GarbageCollector.Mode.Manual:禁用自動GC,但可手動調用System.GC.Collect()或GarbageCollector.CollectIncremental()。
GarbageCollector.Mode.Disabled:完全禁用GC,包括手動調用也無效。
將GarbageCollector.GCMode設置為Disabled即可徹底關閉垃圾回收機制。
使用場景與最佳實踐
禁用GC主要用于性能敏感的關鍵階段,如戰斗、加載、過場動畫等,以避免GC導致的CPU卡頓(GC Spike)。
推薦做法:
1.預分配內存:在進入關鍵階段前,預先分配所需的所有對象(如對象池、緩存等),確保運行時無新內存分配。
2.臨時禁用GC:進入關鍵階段時設置GCMode = Disabled,結束后立即恢復為Enabled或Manual。
3.手動清理:恢復GC后,調用System.GC.Collect()回收階段性內存,防止堆持續增長。
示例流程:
// 進入關卡前
AllocateLevelResources(); // 預分配資源
GarbageCollector.GCMode = GarbageCollector.Mode.Disabled;
// 關卡運行中(避免任何new操作)// 關卡結束
GarbageCollector.GCMode = GarbageCollector.Mode.Enabled;
System.GC.Collect(); // 回收內存
風險與注意事項
內存持續增長:禁用GC后,未引用的對象不會被釋放,若持續分配將導致內存溢出。
必須嚴格控制內存分配:禁止使用字符串拼接、裝箱、Linq、匿名函數等易產生GC的操作。
推薦結合0GC編程:使用StringBuilder、對象池、結構體等技術實現運行時零托管內存分配。
輔助優化手段
啟用增量GC(Incremental GC):在Player Settings中開啟Use Incremental GC,將GC工作分攤到多幀,減少單次停頓時間。
性能監控:使用Profiler或UWA GOT工具監控GC Alloc值,定位內存分配熱點。
綜上,Unity支持運行時禁用GC,但應作為高階優化手段,在可控內存分配的前提下短期使用,以換取更穩定的幀率表現。
From
問答社區
TOP3:為什么不應將游戲邏輯寫在FixedUpdate中?
請問在向別人解釋不要把游戲邏輯放在FixedUpdate,而應正常地放在Update里,除了Input事件外,我還能使用哪些理由呢?
A1:FixedUpdate只處理物理相關的邏輯,Input事件應該放Update。
A2:如果卡,FixedUpdate會在一幀里執行多次來追上更新次數,可能導致嚴重的掉幀和發熱。若想慢點更新,建議用攜程或者用UniTask。
我需要一些硬性的不能做的理由,目前想到的就只有Input事件會重復或被跳過。
A3:那Update里面干什么?而且位置更新不放到Update和渲染匹配不上,看著應該會有頓的感覺。
A4:FixedUpdate不能動態鎖幀,全放里面手機發熱發燙耗電也快。
歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/677b429f682c7e5cd61bf9e4
From
問答社區
TOP4:InstantiateAsync有什么需要特殊處理的嗎?
請教個問題,InstantiateAsync有什么需要特殊處理的嗎?我發現異步實例化出來的角色,好像丟了蒙皮一樣,Mesh完全不跟著動畫、還有根節點動,始終以T-pose的形態呆在固定位置,而且同一個角色,同步加載是正常的。
這是我這邊的環境:
![]()
A1:我們在接近你的版本和更高版本試了下,分別復現了問題和正常加載。查了下可能是類似下面的Unity Bug(異步實例化相關的bug有很多),應該要升一下版本。
![]()
A2: 的確升級Unity版本后ok了。
A3:沒啥問題,效果也比較好、明顯,總得來說異步實例化好處多余壞處,我是調研過了并且項目在使用的。
AsyncInstantiateOperation.GetIntegrationTimeMS() AsyncInstantiateOperation.SetIntegrationTimeMS()可以設置異步實例化的間隔時間,默認是2ms,是Unity 2022.3.20新增加的功能。
寫代碼的時候可以考慮Async/Await,當然國際版Unity最新.3.60,國內版.3.54。
如果你項目沒啥特殊可以考慮升級到最新,正常來說如果你沒有上線最好到最新或者你得平時關注Unity版本發布日志。
歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/67ce97913d306f3e9d594e6c
From
問答社區
TOP5:在Unity轉微信小游戲下,如何用Worker實現多線程?
想用WebWorker計算Unity里的小球的運動軌跡,請問Unity轉微信小游戲的情況下,可以用Worker實現多線程嗎?
A:可以參考官方文檔:https://developers.weixin.qq.com/minigame/dev/api/worker/wx.createWorker.html
功能描述:
創建一個Worker線程。
參數:
string scriptPath
Worker入口文件的絕對路徑
object options:
可選參數:
屬性:useExperimentalWorker
類型:boolean
默認值:false
必填:否
說明:是否使用實驗worker。在iOS下,實驗worker的JS運行效率比非實驗Worker提升數倍,如需在Worker內進行重度計算的建議開啟此選項。同時,實驗Worker存在極小概率會在系統資源緊張時被系統回收,因此建議配合worker.onProcessKilled事件使用,在Worker被回收后可重新創建一個。
最低版本:2.13.0
返回值
Worker
Worker對象
注意事項
接口使用前需要在game.json(插件為plugin.json)中配置workers字段,表示Worker代碼根目錄。
scriptPath為入口文件的絕對路徑,且不以/開頭。
目前限制最多只能創建一個Worker,創建下一個Worker前請先調用Worker.terminate。
多線程Worker指南(小游戲)。
示例代碼
// 創建普通worker
wx.createWorker('workers/index.js')
function createNewWorker() {
const worker = wx.createWorker('workers/index.js', {
useExperimentalWorker: true
})
// 監聽worker被系統回收事件
worker.onProcessKilled(() => {
// 重新創建一個worker
createNewWorker()
})
}
// 創建實驗worker
createNewWorker()
歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/67c559603d306f3e9d594e69
From
問答社區
TOP6:增量GC機制,會導致碎片化更嚴重嗎?
請問增量GC這種頻繁分配與釋放的GC機制,會導致碎片化更嚴重嗎?好像介紹增量GC的資料很少,所以有這種疑問。
A:對于碎片的產生,理論上增量GC和普通GC應該是沒有什么區別的,都是標記-清除。增量GC只是把GC的工作分幀處理了,控制碎片的占用比例更關鍵的是要減少大塊臨時分配。
歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/684fe482682c7e5cd61bfaae
From
問答社區
TOP7:為什么場景中沒有剛體更無碰撞事件,但仍有較高物理耗時?
我有個疑問:為什么GOT性能報告和Profiler里看物理模塊耗時都很高?但其實這時候場景里已經沒有剛體了,按理說不會發生碰撞,只有在代碼里用了Raycast判斷子彈命中,后來我把設置里的物理模擬關掉,又打了包,物理耗時確實降了下來,看子彈還是能正常命中(因為是代碼調的),看粒子里的碰撞也還是能生效。
我不明白的是:之前那么高的物理耗時是在做什么?可能是什么導致的?是有一些我沒留意到的地方用了物理導致的,還是說Unity機制如此?(Unity版本2022.3.59)
A:的確, 當前Unity版本的機制就是這樣,很多時候必須要關閉掉物理模擬(指把Simulation Mode改成Script)才可以節省耗時。具體機制是場景中只要Static Collider數量大于0且沒有關閉物理模擬就會有耗時,和場景中有沒有剛體、有沒有發生碰撞事件無直接關聯。
歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/684688ea682c7e5cd61bfaa0
From
問答社區
TOP8:如何用GPU Instancing來優化樹木草石重復模型?
項目場景里的樹木草石重復模型非常多,在嘗試用GPU Instancing來優化。使用的Shader應該是SRP Batcher和GPU Instancing都支持的,但是材質勾上GPU Instancing后看FrameDebugger里還是走的SRP Batcher,要怎么修改比較好呢?
A:如果 Shader兩個都兼容,就會優先走SRP Batcher的。常規做法就是把規劃要用GPU Instancing的物體用別的不走SRP Batcher的Shader;也可以考慮仍然用兩個都兼容的Shader,但是用MaterialPropertyBlock打斷SRP Batcher,這樣就會順延走GPU Instancing了。
歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/680dd4d53d306f3e9d594ecc
From
問答社區
TOP9:如何在運行時獲取硬件信息?
請問怎樣在運行時獲取硬件信息?一般參考其中哪些信息進行分級比較合理?
A:一般是用SystemInfo里的一些接口,如圖:
![]()
真機上輸出效果如圖:
![]()
一般用其中deviceType、deviceName去找對應的硬件檔次劃分;或者直接graphicsDeviceName給到的GPU型號進行畫質分級。
歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/67f374e1682c7e5cd61bfa35
From
問答社區
TOP10:如何排查優化URP內置Shader冗余?
請教一下Shader冗余應該怎么查,似乎好幾個Shader運行時都有兩份?
A: 資源冗余最常見的原因是AssetBundle沒有依賴打包導致的,可以使用UWA的在線AssetBundle檢測進行冗余檢測先試試。
測了AssetBundle,確實有冗余,但AssetBundle冗余的Shader和運行時冗余的Shader好像又不一致。實際運行時的冗余都是Hidden/Universal Render Pipeline/xxx。這又是為什么呢?
A: 這些是URP的Shader,通常是URP Asset的引用導致的,因為URP Asset會引用這些Shader。而內存中出現兩份Shader,說明內存中出現了兩個來源路徑不一樣的URP Asset,通常一份是在PlayerSetting中引用的URP Asset,另外一份可能來自AssetBundle中動態加載的URP Asset。RendererData里面會引用到PostProcessData,PostProcessData就會引用這些Shader,如果代碼里面動態加載的 AssetBundle 里面也有這種資源,也會引用一份Shader進內存,就會造成冗余。
![]()
![]()
![]()
請問這個怎么處理,直接刪去嗎?
A: 一般只處理內存占用比較大的即可,其他的內存占用比較小,冗余開銷也不大。比如Hidden/Universal Render Pipeline/Uberpost,需要刪除其中用不到的Keyword來降低占用;又比如Hidden/Universal Render Pipeline/HBAO,看是否確實要用到,用不到就解除引用。
歡迎大家轉至社區交流:
https://answer.uwa4d.com/question/69245652244ce21ce9ec095c
無論是社區里開發者們的互助討論,還是AI基于知識沉淀的快速反饋,核心都是為了讓每一個技術難題都有解、每一次踩坑都有回響。本期分享分別來自UWA AI問答和UWA問答社區,希望這些從真實開發場景中提煉的經驗,能直接幫你解決當下的技術卡點,也讓你在遇到同類問題時,能更高效地找到破局方向。
封面圖來源于網絡
今天的分享就到這里。生有涯而知無涯,在漫漫的開發周期中,我們遇到的問題只是冰山一角,UWA社區愿伴你同行,一起探索分享。歡迎更多的開發者加入UWA社區。
UWA官網:www.uwa4d.com
UWA社區:community.uwa4d.com
UWA學堂:edu.uwa4d.com
點擊下方名片關注我們,將我設為星標,及時接收小編每日推送哦,性能優化不迷路~
近期精彩回顧
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.