那些經歷過的Bug Unity的Invoke方法


有一個游戲對象,上面掛着 3 個腳本,如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SaveAndRead : MonoBehaviour {

    public static SaveAndRead instance;
    
    /// <summary>
    /// 保存所有 單獨的DataStore 
    /// </summary>
    public List<DataStore> allAloneDataStores = new List<DataStore>();

    /// <summary>
    /// 初始化SaveAndRead類
    /// </summary>
    public void InitSaveAndRead()
    {
        if (instance == null)
        {
            instance = new SaveAndRead();
        }
    }

    void Awake()
    {
        InitSaveAndRead();
        GetAll_AreaDataStoresInTrigger();
    }
    
    void GetAll_AreaDataStoresInTrigger()
    {
        //拿到所有子物體的  AreaAloneDataStores類
        AreaAloneDataStores[] temp_list02 = GetComponentsInChildren<AreaAloneDataStores>();        
        for (int i = 0; i < temp_list02.Length; i++)
        {
            for (int j = 0; j < temp_list02[i].aloneDataStores.Count; j++)
            {                                
allAloneDataStores.Add(temp_list02[i].aloneDataStores[j]); } } } }
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DistinguishDataStoresInTrigger : MonoBehaviour {

    /// <summary>
    /// 存放單獨游戲對象的類
    /// </summary>
    AreaAloneDataStores temp_AreaAloneDataStorest;
    /// <summary>
    /// 存放觸發Trigger的所有游戲對象的List
    /// </summary>
    public List<GameObject> objs = new List<GameObject>();
    
    void Start()
    {
        //拿到存放單獨游戲對象的類
        temp_AreaAloneDataStorest = gameObject.GetComponent<AreaAloneDataStores>();
        //確保先通過 OnTriggerEnter 拿到游戲對象 , 再調用 GetAllDataStores 拿到游戲對象上的 DataStore
        Invoke("GetAllDataStores", 1f);
    }
    /// <summary>
    /// 拿到所有觸發Trigger的游戲對象
    /// </summary>
    /// <param name="other"></param>
    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.layer == 8)
        {
            objs.Add(other.gameObject);
            other.gameObject.SetActive(false);
        }
    }
    /// <summary>
    /// 拿到所有的DataStore
    /// </summary>
    void GetAllDataStores()
    {
        for (int i = 0; i < objs.Count; i++)
        {
            //拿到 Trigger 的 DataStoreSaveToTrigger 腳本里面存的 DataStore
            DataStore temp_DataStore = objs[i].GetComponent<DataStoreSaveToTrigger>().dataStore;
            //Debug.Log(this.name + "--" + objs[i].name);
            //判斷 DataStore 是否是Alone的,並加到不同的類的List里
            if (temp_DataStore.isAloneSave == true)
            {                
temp_AreaAloneDataStorest.aloneDataStores.Add(temp_DataStore); } } } }
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AreaAloneDataStores : MonoBehaviour {

    /// <summary>
    /// 單獨的DataStore的List
    /// </summary>
    public List<DataStore> aloneDataStores = new List<DataStore>();  
}

Bug:

    代碼的意思是通過 DistinguishDataStoresInTrigger 腳本拿到一些游戲對象,然后對這些游戲對象上的 DataStoreSaveToTrigger 腳本里的 DataStore進行分類,DataStore里的isAloneSave是true時,就把 DataStore 放在 AreaAloneDataStores類 的 aloneDataStores 里。

    當時是有2個 DataStore 的 isAloneSave 是 true ,在 DistinguishDataStoresInTrigger 腳本 進行判斷后,也確實放了2個 DataStore 到 AreaAloneDataStores類 的 aloneDataStores 里,但是在 SaveAndRead腳本 里通過 temp_list02[i].aloneDataStores 來獲得AreaAloneDataStores類 的 aloneDataStores 時,里面卻一個也沒有。

 

原因:

    是 DistinguishDataStoresInTrigger腳本 里的 Invoke("GetAllDataStores", 1f);

    因為它所以在 DistinguishDataStoresInTrigger腳本 執行了 Start 方法 1 秒之后,才開始執行 GetAllDataStores 方法,才把 2 個 DataStore 放到 AreaAloneDataStores類 的 aloneDataStores 里。

    而 SaveAndRead腳本 在Awake 方法里就通過 GetAll_AreaDataStoresInTrigger 方法拿到了 AreaAloneDataStores類 的 aloneDataStores 。

    所以在 SaveAndRead腳本里拿到 AreaAloneDataStores類 的 aloneDataStores 的時候,DistinguishDataStoresInTrigger腳本 還沒有把 2 個 DataStore 放到 AreaAloneDataStores類 的 aloneDataStores 里。

 

解決方法:

    把 SaveAndRead類 Awake 方法里的 GetAll_AreaDataStoresInTrigger();  改為 Invoke("GetAll_AreaDataStoresInTrigger", 2f); 就可以了。

  

 


免責聲明!

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



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