• 对象池技术(unity3d)


    11.5 网络联机对战11-1_哔哩哔哩_bilibili

    优化技术

    面临的问题:

    经常生成重复的对象【可以是游戏对象,也可以是普通对象】

    同样的对象,生命周期短

    例如:子弹、怪物、特效、音效

    问题在哪?频繁的生成和销毁

    缺点:占用了一些内存

     池子是动态的

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class CubeObject : PoolObject {

        private Rigidbody _rigidbody;

        private void Awake()
        {
            _rigidbody = GetComponent();
        }

        public override void OnSpawn()
        {
            //速度归零
            _rigidbody.velocity = Vector3.zero;

            _rigidbody.angularVelocity = Vector3.zero;
        }

        public override void OnPause()
        {
            base.OnPause();
        }
    }
     

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class PoolObject : MonoBehaviour {
        [Header("对象的生命周期")]
        public float lifeTime = 2f;

        public virtual void OnEnable()
        {
            //启动协程
            StartCoroutine(DelayEnterPool());
        }

        ///


        /// 延迟进入对象池
        ///

        ///
        private IEnumerator DelayEnterPool() {
            yield return new WaitForSeconds(lifeTime);
            //进入对象池
            GameObjectPool.Instance.SetGameObject(gameObject);
        }

        ///


        /// 对象出生后要做的事情【初始化操作】
        ///

        public virtual void OnSpawn() {

        }
        ///


        /// 对象进入对象池之前要做的事情
        ///

        public virtual void OnPause() {

        }
    }
     

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class UsePool : MonoBehaviour {    
        // Update is called once per frame
        void Update () {
            if (Input.GetKeyDown(KeyCode.Space)) {
                //获取对象
                GameObjectPool.Instance.GetGameObject("Cube", Vector3.zero, Quaternion.identity);
            }
        }
    }
     

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using System.Reflection;
    using System;


    namespace Utility
    {
        public class Singleton where T : class
        {
            //单例对象
            private static T _singleton;
            //获取单例
            public static T Instance
            {
                get
                {
                    if (_singleton == null)
                    {
                        //如果这样写,那么该类型T必有一个public的构造函数
                        //_singleton = new T();
                        //通过反射的方式,去实例化一个对象出来
                        //派生的单例类中必须要有一个私有的无参构造
                        _singleton = (T)Activator.CreateInstance(typeof(T), nonPublic: true);

                    }
                    return _singleton;
                }
            }
        }
    }
     

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;


    namespace Utility
    {
        public class AssetsManager : Singleton
        {
            //私有构造
            private AssetsManager()
            {
                assetsCache = new Dictionary();
            }

            ///


            /// 资源缓存
            ///

            private Dictionary assetsCache;
            ///


            /// 获取资源
            ///

            ///
            /// 资源路径
            ///

            public Object OldGetAsset(string path)
            {
                //要返回的资源
                Object assetObj = null;
                //如果缓存中没有该资源
                if (!assetsCache.ContainsKey(path))
                {
                    //通过resources加载资源
                    assetObj = Resources.Load(path);
                    //将资源存进缓存
                    assetsCache.Add(path, assetObj);
                }
                else
                {
                    //如果缓存中有,则直接从缓存中拿
                    assetObj = assetsCache[path];
                }

                return assetObj;
            }


            ///新方法---获取资源
            public Object GetAsset(string path)
            {
                //要返回的资源
                Object assetObj = null;
                //尝试从字典中获取该路径所对应的资源
                if (!assetsCache.TryGetValue(path, out assetObj))
                {
                    //通过resources加载资源
                    assetObj = Resources.Load(path);
                    //将资源存进缓存
                    assetsCache.Add(path, assetObj);
                }
                return assetObj;
            }
        }
    }
     

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using Utility;

    public class GameObjectPool {
        #region Singleton
        //单例
        public readonly static GameObjectPool Instance = new GameObjectPool();

        private GameObjectPool() {
            pool = new Dictionary>();
        }

        #endregion

        #region Object Pool
        ///


        /// 对象池
        ///

        Dictionary> pool;

        ///取
        ///从对象池取对象
        ///
        public GameObject GetGameObject(string objName,Vector3 pos, Quaternion rotation) {
            //要返回的游戏对象
            GameObject obj;
            //没有对应的子对象池,或有对应的对象池但池子为空
            if (!pool.ContainsKey(objName) || pool[objName].Count == 0)
            {
                
                //先拿到预设体
                UnityEngine.Object prefab=AssetsManager.Instance.GetAsset(objName);
                //Instantiate生成
                obj=GameObject.Instantiate(prefab,pos,rotation) as GameObject;
                //改名字
                obj.name = objName;
            }
            else {
                //从池子中获取
                obj = pool[objName][0];
                //删除池中对象
                pool[objName].RemoveAt(0);
                //设置位置
                obj.transform.position = pos;
                //设置旋转
                obj.transform.rotation = rotation;
            }
            //激活对象
            obj.SetActive(true);
            try {
                //获取对象脚本
                obj.GetComponent().OnSpawn();
            }
            catch (Exception e) {
                Debug.LogWarning(e);
            }
            //返回对象
            return obj;
        }


        ///存
        ///将对象存入对象池
        ///
        public void SetGameObject(GameObject obj) {
            try
            {
                //获取对象脚本
                obj.GetComponent().OnPause();
            }
            catch (Exception e)
            {
                Debug.LogWarning(e);
            }
            //存入之前,先取消激活
            obj.SetActive(false);
            //判断有没有对应的子对象池
            if (!pool.ContainsKey(obj.name))
            {
                //新建子对象池,并将当前对象存入
                pool.Add(obj.name, new List() { obj });
            }
            else {
                //将当前对象存入对象池
                pool[obj.name].Add(obj);
            }        
        }

        #endregion
    }
     

  • 相关阅读:
    SpringSecurity常见注解的使用
    鸿蒙HarmonyOS DevEco Studio 安装配置
    面渣逆袭:HashMap追魂二十三问
    幼儿园小程序实战开发教程(中篇)
    中断(全网最细!)
    从 Linux 内核角度探秘 JDK NIO 文件读写本质
    docker-compose安装教程
    实习三个月的感悟
    【java】基础语法篇-Java运算符(三)
    Mysql和Oracle实现序列自增
  • 原文地址:https://blog.csdn.net/renwen1579/article/details/126452267