Unity教學項目Ceator Kit:FPS 源代碼學習筆記(三)PoolSystem類(對象池)

using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
using Debug = UnityEngine.Debug;
using Object = UnityEngine.Object;

//Simple ring buffer style pool system. You don't need to return the object to the pool, it just get pushed back to the
//end of the queue again. So use it only for object with short lifespan (projectile, particle system that auto disable)
public class PoolSystem : MonoBehaviour
{
    public static PoolSystem Instance { get; private set; }

    public static void Create()//創建一個對象池系統遊戲對象
    {
        GameObject obj = new GameObject("PoolSystem");
        Instance = obj.AddComponent<PoolSystem>();
    }

    Dictionary<Object, Queue<Object>> m_Pools = new Dictionary<Object, Queue<Object>>();

    public void InitPool(UnityEngine.Object prefab, int size)//初始化對象池
    {
        if(m_Pools.ContainsKey(prefab))//是否有這個預製體
            return;
        
        Queue<Object> queue = new Queue<Object>();//對象隊列

        for (int i = 0; i < size; ++i)//起始設置
        {
            var o = Instantiate(prefab);
            SetActive(o, false);
            queue.Enqueue(o);
        }

        m_Pools[prefab] = queue;//給預製體對應的隊列複製
    }

    public T GetInstance<T>(Object prefab) where T:Object//獲取預製體實例,T爲泛型
    {
        Queue<Object> queue;
        if (m_Pools.TryGetValue(prefab, out queue))//出隊
        {
            Object obj;
            
            if (queue.Count > 0)
            {
                obj = queue.Dequeue(); 
            }
            else
            {
                obj = Instantiate(prefab);
            }
            
            SetActive(obj, true);
            queue.Enqueue(obj);
            
            return obj as T;
        }

        UnityEngine.Debug.LogError("No pool was init with this prefab");
        return null;
    }
    
    static void SetActive(Object obj, bool active)//控制物體是否顯示
    {
        GameObject go = null;

        if (obj is Component component)
        {
            go = component.gameObject;
        }
        else
        {
            go = obj as GameObject;
        }
            
        go.SetActive(active);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章