1. 程式人生 > >關於DontDestroyOnLoad的一點筆記

關於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場景追蹤到所有被標記為DontDestroyOnLoadGameObject,但在物體被使用時,肯定會將它的Parent設定為當前活躍場景的一個物件,所以DontDestroyOnLoad的標籤就被打破了.

具體的可以可以看Unity論壇的問題:撤銷DontDestroyOnLoad.

另外關於一點DontDestroyOnLoad場景的說明:DontDestroyOnLoad並不是一個場景,通過SceneManager獲取到的會是一個Invalid Scene,你也無法通過GetRootGameObjects來獲取該場景的所有跟物體.這個場景僅僅是為了方便在Editor中檢視帶有DontDestroyOnLoad標記的物體而存在的,而在Runtime中是不存在的.Unity手冊中可以找到關於這些的描述:Play mode部分.

如果需要通過找場景的方式來獲取所有帶有DontDestroyOnLoad標記的物體,可以通過一個小科技,具體檢視連結的回答(沒試驗過):
獲取所有DontDestroyOnLoad

物體,並且按照外國友人的說法,這個黑科技也只在Editor中有效.