zoukankan      html  css  js  c++  java
  • Unity对象池PoolManager功能

    对象池的优点有很多博主以及大神都说到,优化了内存,解决了大量的内存消耗..

    对象池类:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 对象池类
    /// </summary>
    public class PoolManager
    {
        //单例
        private static PoolManager instance;
    
        private PoolManager ()
        {
    
        }
    
        public static PoolManager Instance {
            get {
                if (instance == null) {
                    instance = new PoolManager ();
                }
                return instance;
            }
        }
    
        //存储各类型的对象池的集合
        Dictionary<string,Subpool> poolDic = new Dictionary<string, Subpool> ();
    
        /// <summary>
        /// 添加对象池的方法
        /// </summary>
        /// <param name="name">Name.</param>
        void Register (string name)
        {
            GameObject obj = Resources.Load (name)as GameObject;
            Subpool subpool = new Subpool (obj);
            poolDic.Add (name, subpool);
        }
    
        /// <summary>
        /// 获取对象池中游戏对象
        /// </summary>
        /// <param name="name">Name.</param>
        public GameObject Spawn (string name)
        {
            if (!poolDic.ContainsKey (name)) {
                Register (name);
            }
            Subpool subpool = poolDic [name];
            return subpool.SubPoolSpawn ();
        }
    
        /// <summary>
        /// 回收游戏对象
        /// </summary>
        /// <param name="obj">Object.</param>
        public void UnSpawn (GameObject obj)
        {
            foreach (Subpool item in poolDic.Values) {
                if (item.SubPoolContains (obj)) {
                    item.SubPoolUnSpawn (obj);
                    break;
                }
            }
        }
    
        /// <summary>
        /// 清除游戏对象
        /// </summary>
        public void ClearPool ()
        {
            poolDic.Clear ();
        }
    }

       管理相同类型的对象:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 管理相同类型的对象
    /// </summary>
    public class Subpool
    {
        List<GameObject> pool = new List<GameObject> ();
        //要创建的游戏游戏对象预设体
        private GameObject prefab;
    
        //创建的预设体名字
        public Subpool (GameObject obj)
        {
            prefab = obj;
        }
        //返回预设体的名字,定义的预设体的名字与对象池一致,方便池子管理类找对应的池子
        public string name {
            get {
                return prefab.name;
            }
        }
    
        /// <summary>
        /// 从池子中拿对象
        /// </summary>
        /// <returns>The pool spawn.</returns>
        public GameObject SubPoolSpawn ()
        {
            GameObject obj = null;
            //遍历对象池中是否有可以使用的对象
            //有,就激活拿出来使用
            foreach (GameObject item in pool) {
                if (item.activeSelf == false) {
                    obj = item;
                    break;
                }
            }
            if (obj == null) {
                obj = GameObject.Instantiate (prefab)as GameObject;
                pool.Add (obj);
            }
            obj.SetActive (true);
    
            //通过子类实例化接口对象,子类的脚本组件继承并实现了接口中的方法
            //control里面存的是该子类实现的方法,如果要生成一些特效,或者其他游戏行为,那么就可以继承IControl,通过它来进行调用
    
    
            IControl control = obj.GetComponent <IControl> ();
            if (control != null) {
                control.Spawn ();
            }
    
            return obj;
        }
    
        /// <summary>
        /// 回收游戏对象
        /// </summary>
        /// <param name="obj">Object.</param>
        public void SubPoolUnSpawn (GameObject obj)
        {
            IControl control = obj.GetComponent <IControl> ();
            if (control != null) {
                control.UnSpawn ();
            }
            obj.SetActive (false);
        }
    
        /// <summary>
        /// 回收所有的游戏对象
        /// </summary>
        public void SubPoolUnSpawnAll ()
        {
            //回收用于处于激活状态的游戏对象
            foreach (GameObject item in pool) {
                if (item.activeSelf) {
                    SubPoolUnSpawn (item);
                }
            }
        }
    
        /// <summary>
        /// 检查某个游戏对象是否在对象池中
        /// </summary>
        /// <returns><c>true</c>, if pool contains was subed, <c>false</c> otherwise.</returns>
        /// <param name="obj">Object.</param>
        public bool SubPoolContains (GameObject obj)
        {
            return pool.Contains (obj);
        }
    
    }

      取对象和回收对象的接口:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    public interface IControl
    {
    
        //从对象池中取对象的方法
        void Spawn () ;
    
    
        //销毁对象到对象池的方法
        void UnSpawn () ;
    
    }

      调用方式Manager:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 生成子弹,挂载在Manager上
    /// </summary>
    public class CreatBulletScript : MonoBehaviour
    {
        public static CreatBulletScript Instance;
    
        int count = 0;
    
        void Awake ()
        {
            Instance = this;
        }
    
        void SpawnBullet ()
        {
            GameObject temp = PoolManager.Instance.Spawn ("Bullet");
            temp.transform.SetParent (transform);
            temp.transform.localPosition = Vector3.zero;
            count++;
        }
    
        /// <summary>
        /// 可以给外部调用
        /// </summary>
        /// <param name="obj">Object.</param>
        public void UnSpawnBullet (GameObject obj)
        {
            PoolManager.Instance.UnSpawn (obj);
            count--;
        }
    
        void Update ()
        {
            if (Input.GetMouseButtonDown (0)) {
                SpawnBullet ();
            }
        }
    }

      生成的子弹:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 挂载在Bullet上
    /// </summary>
    public class Bullet : MonoBehaviour
    {
    
        float timer = 0;
        /// <summary>
        /// 时间间隔
        /// </summary>
        float timeInterval = 2;
    
        void Update ()
        {
            timer += Time.deltaTime;
            transform.localPosition += new Vector3 (0, 0, 1);
            if (timer >= timeInterval) {
                CreatBulletScript.Instance.UnSpawnBullet (gameObject);
                timer = 0;
            }
        }
    }

      PoolManager.unitypackage.zip Demo下载

     对象池优化版,在Spawn的时候,对它进行赋值操作..

    SubPool:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 管理相同类型的对象
    /// </summary>
    public class Subpool
    {
        List<GameObject> pool = new List<GameObject>();
        //要创建的游戏游戏对象预设体
        private GameObject prefab;
    
        //创建的预设体名字
        public Subpool(GameObject obj)
        {
            prefab = obj;
        }
        //返回预设体的名字,定义的预设体的名字与对象池一致,方便池子管理类找对应的池子
        public string name
        {
            get
            {
                return prefab.name;
            }
        }
    
        /// <summary>
        /// 从池子中拿对象
        /// </summary>
        /// <returns>The pool spawn.</returns>
        public GameObject SubPoolSpawn(Transform parent, Vector3 position, Quaternion quaternion)
        {
            GameObject obj = null;
            //遍历对象池中是否有可以使用的对象
            //有,就激活拿出来使用
            foreach (GameObject item in pool)
            {
                if (item.activeSelf == false)
                {
                    obj = item;
                    break;
                }
            }
            if (obj == null)
            {
                obj = GameObject.Instantiate(prefab) as GameObject;
                pool.Add(obj);
            }
            obj.transform.position = position;
            obj.transform.rotation = quaternion;
            obj.transform.SetParent(parent);
            obj.SetActive(true);
            //通过子类实例化接口对象,子类的脚本组件继承并实现了接口中的方法
         //control里面存的是该子类实现的方法,如果要生成一些特效,或者其他游戏行为,那么就可以继承IControl,通过它来进行调用
            IControl control = obj.GetComponent<IControl>();
            if (control != null)
            {
                control.Spawn();
            }
    
            return obj;
        }
    
        /// <summary>
        /// 回收游戏对象
        /// </summary>
        /// <param name="obj">Object.</param>
        public void SubPoolUnSpawn(GameObject obj)
        {
            IControl control = obj.GetComponent<IControl>();
            if (control != null)
            {
                control.UnSpawn();
            }
            obj.SetActive(false);
        }
    
        /// <summary>
        /// 回收所有的游戏对象
        /// </summary>
        public void SubPoolUnSpawnAll()
        {
            //回收用于处于激活状态的游戏对象
            foreach (GameObject item in pool)
            {
                if (item.activeSelf)
                {
                    SubPoolUnSpawn(item);
                }
            }
        }
    
        /// <summary>
        /// 检查某个游戏对象是否在对象池中
        /// </summary>
        /// <returns><c>true</c>, if pool contains was subed, <c>false</c> otherwise.</returns>
        /// <param name="obj">Object.</param>
        public bool SubPoolContains(GameObject obj)
        {
            return pool.Contains(obj);
        }
    
    }

    PoolManager:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    /// <summary>
    /// 对象池类
    /// </summary>
    public class PoolManager
    {
        //单例
        private static PoolManager instance;
    
        private PoolManager()
        {
    
        }
    
        public static PoolManager Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new PoolManager();
                }
                return instance;
            }
        }
    
        //存储各类型的对象池的集合
        Dictionary<string, Subpool> poolDic = new Dictionary<string, Subpool>();
    
        /// <summary>
        /// 添加对象池的方法
        /// </summary>
        /// <param name="name">Name.</param>
        void Register(GameObject _obj)
        {
            GameObject obj = _obj;
            Subpool subpool = new Subpool(obj);
            poolDic.Add(obj.name, subpool);
        }
    
        /// <summary>
        /// 获取对象池中游戏对象
        /// </summary>
        /// <param name="name">Name.</param>
        public GameObject Spawn(GameObject obj, Transform parent, Vector3 position, Quaternion quaternion)
        {
            if (!poolDic.ContainsKey(obj.name))
            {
                Register(obj);
            }
            Subpool subpool = poolDic[obj.name];
            return subpool.SubPoolSpawn(parent, position, quaternion);
        }
    
        /// <summary>
        /// 回收游戏对象
        /// </summary>
        /// <param name="obj">Object.</param>
        public void UnSpawn(GameObject obj)
        {
            foreach (Subpool item in poolDic.Values)
            {
                if (item.SubPoolContains(obj))
                {
                    item.SubPoolUnSpawn(obj);
                    break;
                }
            }
        }
    
        /// <summary>
        /// 清除游戏对象
        /// </summary>
        public void ClearPool()
        {
            poolDic.Clear();
        }
    }

     Bullet中:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    /// <summary>
    /// 挂载在Bullet上
    /// </summary>
    public class Bullet : MonoBehaviour, IControl
    {
        protected ParticleSystem[] pss;
        float timer = 0;
        /// <summary>
        /// 时间间隔
        /// </summary>
        float timeInterval = 2;
        void Awake()
        {
            pss = transform.GetComponentsInChildren<ParticleSystem>();
        }
    
        public void Spawn()
        {
            Debug.Log("Spawn");
            PlayEffect();
        }
    
        public void UnSpawn()
        {
            Debug.Log("UnSpawn");
            ResetEffect();
        }
    
        void Update()
        {
            timer += Time.deltaTime;
            transform.localPosition += new Vector3(0, 0, 1);
            if (timer >= timeInterval)
            {
                CreatBulletScript.Instance.UnSpawnBullet(gameObject);
                timer = 0;
            }
        }
        /// <summary>
        /// 播放特效
        /// </summary>
        void PlayEffect()
        {
            foreach (var item in pss)
            {
                item.Play();
            }
        }
    
        /// <summary>
        /// 结束特效
        /// </summary>
        void ResetEffect()
        {
            foreach (var item in pss)
            {
                item.Stop();
            }
        }
    }

     GitHub 链接 : https://github.com/KinJin-Ristina/PoolManager 

  • 相关阅读:
    【LeetCode】048. Rotate Image
    【LeetCode】036. Valid Sudoku
    【LeetCode】060. Permutation Sequence
    【LeetCode】001. Two Sum
    【LeetCode】128. Longest Consecutive Sequence
    【LeetCode】081. Search in Rotated Sorted Array II
    【LeetCode】033. Search in Rotated Sorted Array
    顺时针打印矩阵
    矩形覆盖
    二维数组中的查找
  • 原文地址:https://www.cnblogs.com/jbw752746541/p/9797815.html
Copyright © 2011-2022 走看看