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 

  • 相关阅读:
    【PAT】1020. Tree Traversals (25)
    Pongo建立信号基站-实际上还是考中位数
    从此不再惧怕URI编码:JavaScript及C# URI编码详解
    WebBrowser与IE的关系,如何设置WebBrowser工作在IE9模式下?
    命令行下开启与关闭windows防火墙关端口(转)
    MySql数据库批量备份命令
    C#检查文件是否被占用
    C#使用Gzip解压缩完整读取网页内容
    [转]免费电话网专用免费平台
    libQt5Core.so: undefined reference to `dlclose@GLIBC_2.4'
  • 原文地址:https://www.cnblogs.com/jbw752746541/p/9797815.html
Copyright © 2011-2022 走看看