1. 程式人生 > >Objectpool (物件池) 帶例項

Objectpool (物件池) 帶例項

之前發了快取池的用法,那麼索性把物件池也寫一個把。

首先是Unity佈置:

程式碼直接給“Main Camera”

預製體新增剛體:也就是要發射的子彈。

Poolable程式碼:

public class Poolable : MonoBehaviour
{
    public string key;
    public bool isPooled;
}

POOL程式碼:

public class POOLc : MonoBehaviour
{
    const string PoolKey = "";
    [SerializeField]//序列化域,可以序列化非公有非靜態域用[SerializeField]屬性標記。不可以序列化靜態域/不可以序列化屬性  序列化的型別有:
                    //- All classed inheriting from UnityEngine.Object, for example Gameobject, Commponent, MonoBehaviour, Texture2D, AnimationClip.. - All basic data types like int, string, float, bool. - Some built in types like Vector2, Vector3, Vector4, Quaternion, Matrix4x4, Color, Rect, Layermask.. - Arrays of a serializable type 
                    //- 所有繼承自UnityEngine.Object的類,例如GameObject,Component,MonoBehaviour,Texture2D,AnimationClip..- 所有基本型別像int,string,float,bool.- 一些內建型別像Vector2,Vector3,Vector4,Quaternion,Matrix4x4,Color,Rect,Layermask..- 一個序列化型別的Array(陣列) 
    GameObject prefab;
    List<Poolable> instances = new List<Poolable>();
    public Transform Mytrans;
    bool isFire = false;
    Poolable obj;
    void Start()
    {
        if (GameObjectPoolController.AddEntry(PoolKey, prefab, 5, 10))
            Debug.Log("預填充池");
        else
            Debug.Log("池已配置");
       
    }
    void Update()
    {

        if (Input.GetMouseButtonDown(0))
        {

            obj = GameObjectPoolController.Dequeue(PoolKey);
            obj.gameObject.SetActive(true);
            instances.Add(obj);
            isFire = true;

        }
        if (instances.Count > 1)
        {
            Poolable obj = instances[0];
            instances.RemoveAt(0);
            GameObjectPoolController.Enqueue(obj);
        }
        if (isFire)
        {
            obj.GetComponent<Rigidbody>().velocity = new Vector3(0,0,-100);
            obj.transform.position = Mytrans.position;
            obj.transform.forward = Mytrans.forward;
            isFire = false;
        }

    }
   
}

PoolData程式碼:

public class PoolData
{  

    public GameObject prefab;//預設
    public int maxCount;//變數最大個數
    public Queue<Poolable> pool;//預填充列
}

public class GameObjectPoolController : MonoBehaviour
{
   //單例
    static GameObjectPoolController Instance
    {
        get
        {
            if (instance == null) 
               CreateSharedInstance();
            return instance;
        }
    }
    static GameObjectPoolController instance;

    static Dictionary<string, PoolData> pools = new Dictionary<string, PoolData>();
  

  
    void Awake()
    {
        if (instance != null && instance != this)
            Destroy(this);
        else
            instance = this;
    }
   

   //設定儲存最大值
    public static void SetMaxCount(string key, int maxCount)
    {
        if (!pools.ContainsKey(key))
            return;
        PoolData data = pools[key];
        data.maxCount = maxCount;
    }
    //入倉
    public static bool AddEntry(string key, GameObject prefab, int prepopulate, int maxCount)
    {
        if (pools.ContainsKey(key))
            return false;

        PoolData data = new PoolData();
        data.prefab = prefab;
        data.maxCount = maxCount;
        data.pool = new Queue<Poolable>(prepopulate);
        pools.Add(key, data);

        for (int i = 0; i < prepopulate; ++i)
            Enqueue(CreateInstance(key, prefab));

        return true;
    }
    //清倉
    public static void ClearEntry(string key)
    {
        if (!pools.ContainsKey(key))
            return;

        PoolData data = pools[key];
        while (data.pool.Count > 0)
        {
            Poolable obj = data.pool.Dequeue();
            GameObject.Destroy(obj.gameObject);
        }
        pools.Remove(key);
    }

    internal static void Enqueue(List<Poolable> instances)
    {
        throw new NotImplementedException();
    }
    //入隊
    public static void Enqueue(Poolable sender)
    {
        if (sender == null || sender.isPooled || !pools.ContainsKey(sender.key))
            return;

        PoolData data = pools[sender.key];
        if (data.pool.Count >= data.maxCount)
        {
            GameObject.Destroy(sender.gameObject);
            return;
        }

        data.pool.Enqueue(sender);
        sender.isPooled = true;
        sender.transform.SetParent(Instance.transform);
        sender.gameObject.SetActive(false);
    }
    //出隊
    public static Poolable Dequeue(string key)
    {
        if (!pools.ContainsKey(key))
            return null;

        PoolData data = pools[key];
        if (data.pool.Count == 0)
            return CreateInstance(key, data.prefab);

        Poolable obj = data.pool.Dequeue();
        obj.isPooled = false;
        return obj;
    }


   // 建立共享例項  主要是建立一個不銷燬的父物體
    static void CreateSharedInstance()
    {
        GameObject obj = new GameObject("GameObject Pool Controller");
        DontDestroyOnLoad(obj);
        instance = obj.AddComponent<GameObjectPoolController>();
    }

    static Poolable CreateInstance(string key, GameObject prefab)
    {
        GameObject instance = Instantiate(prefab) as GameObject;
        Poolable p = instance.AddComponent<Poolable>();
        p.key = key;
        return p;
    }
   
}

效果圖:

Demo連結:https://pan.baidu.com/s/1_P2S-Jr4eaBymJK3UsyUYw 密碼:tp49