先前完成的缓存池模块的缺点

image.png

  • 很多缓存池对象在hierarchy面板上,不方便管理,可以进行优化
  • 切场景时,缓存池里的对象都会被删除,但是仍然在列表中保持连接,应该提供一个清除缓存池的方法

代码

  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>() { obj };
  19. //obj.transform.parent = fatherObj.transform;
  20. //obj.SetActive(false);
  21. poolList = new List<GameObject>() {};
  22. PushObj(obj);
  23. }
  24. /// <summary>
  25. /// 往抽屉里面压东西
  26. /// </summary>
  27. /// <param name="obj"></param>
  28. public void PushObj(GameObject obj)
  29. {
  30. // 失活 让其隐藏
  31. obj.SetActive(false);
  32. // 存起来
  33. poolList.Add(obj);
  34. // 设置父对象
  35. obj.transform.parent = fatherObj.transform;
  36. }
  37. /// <summary>
  38. /// 从抽屉里面取东西
  39. /// </summary>
  40. /// <returns></returns>
  41. public GameObject GetObj()
  42. {
  43. GameObject obj = null;
  44. // 取出第一个
  45. obj = poolList[0];
  46. poolList.RemoveAt(0);
  47. // 激活 让其显示
  48. obj.SetActive(true);
  49. // 断开父子关系
  50. obj.transform.parent = null;
  51. return obj;
  52. }
  53. }
  54. /// <summary>
  55. /// 缓存池模块
  56. /// </summary>
  57. public class PoolMgr : BaseManager<PoolMgr> // 单例模式
  58. {
  59. public Dictionary<string,PoolData> poolDic = new Dictionary<string, PoolData>();
  60. // 作为根节点
  61. private GameObject poolObj;
  62. /// <summary>
  63. /// 往外拿东西
  64. /// </summary>
  65. /// <param name="name">规定预设体的路径作为抽屉的名字</param>
  66. /// <returns></returns>
  67. public GameObject GetObj(string name)
  68. {
  69. GameObject obj = null;
  70. // 有抽屉且抽屉里有东西
  71. if (poolDic.ContainsKey(name) && poolDic[name].poolList.Count > 0)
  72. {
  73. obj = poolDic[name].GetObj();
  74. }
  75. else
  76. {
  77. // 抽屉里没有,则实例化一个新的返回出去
  78. // 规定预设体的路径作为抽屉的名字
  79. obj = GameObject.Instantiate(Resources.Load<GameObject>(name));
  80. obj.name = name; // 让对象的名字和外面传进来的名字一样,即资源路径名,也是我们规定的抽屉名,方便存进池子时获取名字
  81. }
  82. return obj;
  83. }
  84. /// <summary>
  85. /// 还暂时不用的对象
  86. /// </summary>
  87. public void PushObj(string name, GameObject obj)
  88. {
  89. if (poolObj == null)
  90. poolObj = new GameObject("Pool");
  91. // 里面有抽屉
  92. if (poolDic.ContainsKey(name))
  93. {
  94. poolDic[name].PushObj(obj);
  95. }
  96. // 里面没有抽屉
  97. else
  98. {
  99. poolDic.Add(name, new PoolData(obj,poolObj));
  100. }
  101. }
  102. /// <summary>
  103. /// 情况缓存池的方法,主要用于场景切换时
  104. /// </summary>
  105. public void Clear()
  106. {
  107. poolDic.Clear();
  108. poolObj = null; // 切场景时父对象也会被移除
  109. }
  110. }

优化效果

动画.gif