Unity3D中關於場景銷毀時事件調用順序的一點記錄


先說一下我遇到的問題,我弄了一個對象池管理多個對象,對象池綁定在一個GameObject上,每個對象在OnBecameInvisible時會進行回收(即移出屏幕就回收),但是當場景切換或停止運行程序時場景中如果還有待回收的對象,就會報錯,報錯顯示的信息為,我的對象池GameObject已經被銷毀了雲雲,因為回收的對象我會把他們作為綁定了對象池的GameObject的子級來方便管理。

所以唯一的可能就是腳本方法調用順序不可控,即不同GameObject的OnBecameInvisible在其它GameObject的OnDestroy之后調用。

在Unity3D中,我們知道GameObject的Update和LateUpdate兩個函數的執行順序是:每一幀中所有GameObject的Update方法都優先LateUpdate方法執行,即所有GameObject的Update方法都執行完畢才會執行LateUpdate方法。

那么我在使用下面3個方法時也認為其執行順序也同Update和LateUpdate一致:

  • OnBecameInvisible:當GameObject存在renderer屬性時,消失(不渲染)時會調用;
  • OnDisable:SetActivite(false)時調用;
  • OnDestroy:銷毀時調用;

我認為在關閉程序或場景銷毀時,其調用順序是所有GameObject的OnBecameInvisible調用完畢后才開始調用OnDisable,最后再統一調用OnDestroy方法,即和Update與LateUpdate邏輯一致。

但是實際上並不是這樣,對於每個GameObject來說,實際調用順序是OnDisable->OnBecameInvisible->OnDestroy,但是在多個GameObject直接不能保證調用順序,可能第一個GameObject的OnDestroy已經調用了,另一個的OnDisable才開始調用,大家可以用下面的腳本在場景中多放幾個GameObject測試一下看看,注意要添加一個顯示的東西,比如Cube,否則OnBecameInvisible不會調用到。

 1 using UnityEngine;
 2 using System.Collections;
 3 
 4 public class NewBehaviourScript : MonoBehaviour
 5 {
 6     public string name;
 7 
 8     void OnBecameInvisible()
 9     {
10         Debug.Log(name + " : OnBecameInvisible");
11     }
12 
13     void OnDisable()
14     {
15         Debug.Log(name + " : OnDisable");
16     }
17     
18     void OnDestroy()
19     {
20         Debug.Log(name + " : OnDestroy");
21     }
22 }

結果可以印證多個GameObject之間的方法調用順序不能保證,所以我們開發程序在遇到場景銷毀時管理一些對象時要注意。

我的解決方法:

實在想不出更好的辦法了,要么讓對象池GameObject在切換場景時不銷毀,要么只有添加判斷,如果對象池GameObject已經銷毀了就不要進行對象回收。

大家可以參考一下國外的這個問題:

http://answers.unity3d.com/questions/505088/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM