Unity对象池封装
1、应用场景:
对一些游戏场景:需要多次创建和销毁的对象【如枪战游戏里的子弹、RPG游戏里的剧情小怪...】
2、为什么要使用对象池:
可以减少GC的次数,提高游戏性能
3、对象池原理:
a、需要生成对象时,先判断容器里是否存在可用的该类型对象,存在则直接取,不存在就实例化
b、将需要销毁的对象保存而不删除【设置不可见,保存在容器中】
4、具体实现:【将对象池比作为衣柜,衣柜里有好多抽屉,不同抽屉放置不同类型的衣服】
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PoolObj : SingletonBase<PoolObj> { public Dictionary<string, List<GameObject>> poolDict = new Dictionary<string, List<GameObject>>(); public GameObject GetObj(string name) { GameObject obj = null; //如果衣橱里有该类型抽屉 并且 该抽屉 有可用的衣服 if (poolDict.ContainsKey(name) && poolDict[name].Count > 0) { //取出目标衣服,在抽屉里移除衣服 obj = poolDict[name][0]; poolDict[name].RemoveAt(0); } else { //创建衣服 obj = GameObject.Instantiate(Resources.Load<GameObject>(name)); obj.name = name;//将对象名字设置为 预制体 名字 } obj.SetActive(true); return obj; } public void PushObj(string name,GameObject obj) { obj.SetActive(false); //如果衣柜里有该类型抽屉 if (poolDict.ContainsKey(name)) { //直接在相应抽屉里添加衣服 poolDict[name].Add(obj); } else { //衣柜里没有该抽屉 则 创建抽屉 poolDict.Add(name, new List<GameObject>() { obj}); } } }
预制体上挂上延迟销毁的代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class delayPush : MonoBehaviour { void OnEnable() { Invoke("Push", 1);//延迟1秒放入对象池 } void Push()//调用对象池 放入管理方法 { PoolObj.GetInstance().PushObj(this.gameObject.name,this.gameObject); } }
测试代码:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameStart : MonoBehaviour { void Update() { if (Input.GetMouseButtonDown(0)) { PoolObj.GetInstance().GetObj("Pool/Cube");//预制体路径 } if (Input.GetMouseButtonDown(1)) { PoolObj.GetInstance().GetObj("Pool/Cube2"); } } }
效果:
评论