關於DontDestroyOnLoad的一點筆記
關於DontDestroyOnLoad的一點筆記
由於Unity中例項化GameObject
的代價是比較高的,所以專案利用DontDestroyOnLoad
做了一個可重複回收再利用的東西,關鍵程式碼是:Instantiate
預設之後,呼叫DontDestoryOnLoad
來包裝一次,並且用一個列表List來儲存這個物體的引用,當物體不再使用時,使用transform.SetParent(null,false)
來隱藏掉.最後在這個介面被OnDestroy時,手動Destroy掉List裡的每一個物體.
拋開設計思路不談,問題是當遊戲切換場景時,會丟擲錯誤,雖然不影響實際遊戲,但畢竟是個Error:MissingReferenceException: The object of type 'AppComment' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object.
這顯然是物體被Destroy了兩次,意味著在場景被Unload
的時候物體已經被摧毀了,然後再次在腳本里Destroy
的時候就報錯了.怎麼回事呢?很久之前在看這個問題了,今天又在網上查了半天,原來是當GameObject
被使用後,會破壞掉DontDestroyOnLoad
的標記.在Editor裡面我們可以在DontDestroyOnLoad
場景追蹤到所有被標記為DontDestroyOnLoad
的GameObject
,但在物體被使用時,肯定會將它的Parent
設定為當前活躍場景的一個物件,所以DontDestroyOnLoad
的標籤就被打破了.
具體的可以可以看Unity論壇的問題:撤銷DontDestroyOnLoad.
另外關於一點DontDestroyOnLoad場景的說明:DontDestroyOnLoad並不是一個場景,通過SceneManager獲取到的會是一個Invalid Scene,你也無法通過GetRootGameObjects
來獲取該場景的所有跟物體.這個場景僅僅是為了方便在Editor中檢視帶有DontDestroyOnLoad
標記的物體而存在的,而在Runtime中是不存在的.Unity手冊中可以找到關於這些的描述:Play mode部分.
如果需要通過找場景的方式來獲取所有帶有DontDestroyOnLoad
標記的物體,可以通過一個小科技,具體檢視連結的回答(沒試驗過):
獲取所有DontDestroyOnLoad