[Unity学习教程] Unity-缓存池

[复制链接]
查看1322 | 回复0 | 2023-8-23 12:07:55 | 显示全部楼层 |阅读模式 来自 中国北京
一、.基础缓存池实现



继承的Singleton脚本为
  1. public class Singleton<T> where T : new()
  2. {
  3.     private static T _instance;
  4.     public static T GetIstance()
  5.     {
  6.         if (_instance == null)
  7.             _instance = new T();
  8.         return _instance;
  9.     }
  10. }
复制代码
1.PoolManager

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Events;
  5. /// <summary>
  6. /// 抽屉数据  池子中的一列容器
  7. /// </summary>
  8. public class PoolData
  9. {
  10.     //抽屉中 对象挂载的父节点
  11.     public GameObject fatherObj;
  12.     //对象的容器
  13.     public List<GameObject> poolList;
  14.     /// <summary>
  15.     /// 对象池-根节点-父节点-对象
  16.     /// </summary>
  17.     /// <param name="obj">对象</param>
  18.     /// <param name="poolObj">根节点</param>
  19.     public PoolData(GameObject obj, GameObject poolObj)
  20.     {
  21.         //给我们的抽屉 创建一个父对象 并且把他作为我们pool(衣柜)对象的子物体
  22.         fatherObj = new GameObject(obj.name);
  23.         fatherObj.transform.parent = poolObj.transform;
  24.         poolList = new List<GameObject>() { };
  25.         PushObj(obj);
  26.     }
  27.     /// <summary>
  28.     /// 往抽屉里面 压都东西
  29.     /// </summary>
  30.     /// <param name="obj"></param>
  31.     public void PushObj(GameObject obj)
  32.     {
  33.         //失活 让其隐藏
  34.         obj.SetActive(false);
  35.         //存起来
  36.         poolList.Add(obj);
  37.         //设置父对象
  38.         obj.transform.parent = fatherObj.transform;
  39.     }
  40.     /// <summary>
  41.     /// 从抽屉里面 取东西
  42.     /// </summary>
  43.     /// <returns></returns>
  44.     public GameObject GetObj()
  45.     {
  46.         GameObject obj = null;
  47.         //取出第一个
  48.         obj = poolList[0];
  49.         poolList.RemoveAt(0);
  50.         //激活 让其显示
  51.         obj.SetActive(true);
  52.         //断开了父子关系
  53.         obj.transform.parent = null;
  54.         return obj;
  55.     }
  56. }
  57. /// <summary>
  58. /// 缓存池模块
  59. /// 1.Dictionary List
  60. /// 2.GameObject 和 Resources 两个公共类中的 API
  61. /// </summary>
  62. public class PoolMgr : Singleton<PoolMgr>
  63. {
  64.     //缓存池容器 (衣柜)
  65.     public Dictionary<string, PoolData> poolDic = new Dictionary<string, PoolData>();
  66.     //创建根节点
  67.     private GameObject poolObj;
  68.     /// <summary>
  69.     /// 从缓存池中往外拿东西
  70.     /// </summary>
  71.     /// <param name="name"></param>
  72.     /// <returns></returns>
  73.     public void GetObj(string name,UnityAction<GameObject> callBcak )
  74.     {
  75.         //1.衣柜中有抽屉,抽屉里有东西
  76.         if (poolDic.ContainsKey(name) && poolDic[name].poolList.Count > 0)
  77.         {
  78.             callBcak(poolDic[name].GetObj());
  79.         }
  80.         //2.抽屉中无东西
  81.         else
  82.         {
  83.             //缓存池中没有,从resources文件夹下拿Cube预制体
  84.             //obj = GameObject.Instantiate(Resources.Load<GameObject>(name));
  85.             //通过异步加载资源创建对象 给外部调用
  86.             ResMgr.GetInstance().LoadAsync<GameObject>(name, (o) =>
  87.             {
  88.                 o.name = name;
  89.                 callBcak(o);
  90.             });
  91.             //将对象名字修改为池名字
  92.             //obj.name = name;
  93.         }
  94.     }
  95.     /// <summary>
  96.     /// 存入缓存池
  97.     /// </summary>
  98.     public void PushObj(string name, GameObject obj)
  99.     {
  100.         //判断Pool是否为空
  101.         if (poolObj == null)
  102.             poolObj = new GameObject("Pool");
  103.         //1.有抽屉
  104.         if (poolDic.ContainsKey(name))
  105.         {
  106.             poolDic[name].PushObj(obj);
  107.         }
  108.         //2.没有抽屉
  109.         else
  110.         {
  111.             //创建抽屉
  112.             poolDic.Add(name, new PoolData(obj, poolObj));
  113.         }
  114.     }
  115.     /// <summary>
  116.     /// 清空缓存池的方法
  117.     /// 主要用在 场景切换时
  118.     /// </summary>
  119.     public void Clear()
  120.     {
  121.         poolDic.Clear();
  122.         poolObj = null;
  123.     }
  124. }
复制代码
2.Test

挂载到摄像机上
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class Test : MonoBehaviour
  5. {
  6.     void Update()
  7.     {
  8.         if (Input.GetMouseButtonDown(0))
  9.         {
  10.             //路径名
  11.             PoolMgr.GetInstance().GetObj("Test/Cube", (o) => { });
  12.         }
  13.     }
  14. }
复制代码
3.DlaySave

挂载到预制体Cube上
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class DelaySave : MonoBehaviour
  5. {
  6.     //当对象激活时,进入生命周期函数
  7.     void OnEnable()
  8.     {
  9.         Invoke("Save", 1);
  10.     }
  11.     void Save()
  12.     {
  13.         PoolManager.GetIstance().SaveObj(this.gameObject.name, this.gameObject);
  14.     }
  15. }
复制代码


二、缓存池优化

在天生物体时设置为Pool的子物体












 

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. /// <summary>
  5. /// 抽屉数据  池子中的一列容器
  6. /// </summary>
  7. public class PoolData
  8. {
  9.     //抽屉中 对象挂载的父节点
  10.     public GameObject fatherObj;
  11.     //对象的容器
  12.     public List<GameObject> poolList;
  13.     public PoolData(GameObject obj, GameObject poolObj)
  14.     {
  15.         //给我们的抽屉 创建一个父对象 并且把他作为我们pool(衣柜)对象的子物体
  16.         fatherObj = new GameObject(obj.name);
  17.         fatherObj.transform.parent = poolObj.transform;
  18.         poolList = new List<GameObject>() { };
  19.         PushObj(obj);
  20.     }
  21.     /// <summary>
  22.     /// 往抽屉里面 压都东西
  23.     /// </summary>
  24.     /// <param name="obj"></param>
  25.     public void PushObj(GameObject obj)
  26.     {
  27.         //失活 让其隐藏
  28.         obj.SetActive(false);
  29.         //存起来
  30.         poolList.Add(obj);
  31.         //设置父对象
  32.         obj.transform.parent = fatherObj.transform;
  33.     }
  34.     /// <summary>
  35.     /// 从抽屉里面 取东西
  36.     /// </summary>
  37.     /// <returns></returns>
  38.     public GameObject GetObj()
  39.     {
  40.         GameObject obj = null;
  41.         //取出第一个
  42.         obj = poolList[0];
  43.         poolList.RemoveAt(0);
  44.         //激活 让其显示
  45.         obj.SetActive(true);
  46.         //断开了父子关系
  47.         obj.transform.parent = null;
  48.         return obj;
  49.     }
  50. }
  51. /// <summary>
  52. /// 缓存池模块
  53. /// 1.Dictionary List
  54. /// 2.GameObject 和 Resources 两个公共类中的 API
  55. /// </summary>
  56. public class PoolMgr : Singleton<PoolMgr>
  57. {
  58.     //缓存池容器 (衣柜)
  59.     public Dictionary<string, PoolData> poolDic = new Dictionary<string, PoolData>();
  60.     private GameObject poolObj;
  61.     /// <summary>
  62.     /// 往外拿东西
  63.     /// </summary>
  64.     /// <param name="name"></param>
  65.     /// <returns></returns>
  66.     public GameObject GetObj(string name)
  67.     {
  68.         GameObject obj = null;
  69.         //有抽屉 并且抽屉里有东西
  70.         if (poolDic.ContainsKey(name) && poolDic[name].poolList.Count > 0)
  71.         {
  72.             obj=poolDic[name].GetObj();
  73.         }
  74.         else
  75.         {
  76.             obj = GameObject.Instantiate(Resources.Load<GameObject>(name));
  77.             //把对象名字改的和池子名字一样
  78.             obj.name = name;
  79.         }
  80.         return obj;
  81.     }
  82.     /// <summary>
  83.     /// 换暂时不用的东西给我
  84.     /// </summary>
  85.     public void PushObj(string name, GameObject obj)
  86.     {
  87.         if (poolObj == null)
  88.             poolObj = new GameObject("Pool");
  89.         //里面有抽屉
  90.         if (poolDic.ContainsKey(name))
  91.         {
  92.             poolDic[name].PushObj(obj);
  93.         }
  94.         //里面没有抽屉
  95.         else
  96.         {
  97.             poolDic.Add(name, new PoolData(obj, poolObj));
  98.         }
  99.     }
  100.     /// <summary>
  101.     /// 清空缓存池的方法
  102.     /// 主要用在 场景切换时
  103.     /// </summary>
  104.     public void Clear()
  105.     {
  106.         poolDic.Clear();
  107.         poolObj = null;
  108.     }
  109. }
复制代码


来源:https://blog.csdn.net/weixin_53163894/article/details/132037520
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则