Objectpool (对象池) 带实例

版权声明:转载请注明出处。 https://blog.csdn.net/QWBin/article/details/82777334

之前发了缓存池的用法,那么索性把对象池也写一个把。

首先是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()
    {

扫描二维码关注公众号,回复: 3996842 查看本文章

        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

猜你喜欢

转载自blog.csdn.net/QWBin/article/details/82777334