Unity对象池技术
发表于2018-03-21
在游戏中,会出现对游戏对象进行反复的创建销毁的情况,比如游戏中的子弹,敌人等,但反复的创建与销毁会浪费一定的系统资源,此种情况下一般会引入对象池技术,可以将暂时不需要用到游戏对象放在对象池(缓冲区),当需要使用到时再从对象池中提取。下面就通过一个简单的项目DEMO,帮助大家去学习了解关于对象池的知识。
代码如下:
using UnityEngine; using System.Collections.Generic; public class PoolManager : MonoBehaviour { /// <summary> ///当游戏中只有一个对象需要用到对象池 /// </summary> public List<GameObject> singlePool; /// <summary> /// 当游戏中有多个游戏对象需要用到对象池 /// </summary> public Dictionary<int, List<GameObject>> mostPool; /// <summary> /// 单例模式 /// </summary> public static PoolManager manager; public static PoolManager GetInstance() { if (manager != null) { manager = new PoolManager(); } return manager; } /// <summary> /// 从对象池中创建单个游戏对象 /// </summary> public GameObject CreateSingleGameobject(GameObject obj,Vector3 position,Quaternion rotation) { if(singlePool.Count>0) { GameObject m_obj=singlePool[0]; singlePool.Remove(m_obj); m_obj.SetActive(true); m_obj.transform.position = position; m_obj.transform.rotation = rotation; return m_obj; } return GameObject.Instantiate(obj, position, rotation) as GameObject; } /// <summary> /// 将游戏对象取消激活,隐藏起来 /// 并将其添加到对象池中,为了减少资源的浪费,不需要进行销毁 /// </summary> /// <param name="obj"></param> public void HideSingleGameobject(GameObject obj) { //使其处于未机会隐藏状态 obj.SetActive(false); //将其添加到对象池中 singlePool.Add(obj); } /// <summary> /// 当游戏中有多个游戏对象需要在对象池中创建时 /// </summary> /// <param name="obj">需要激活的游戏对象</param> /// <param name="position"></param> /// <param name="rotation"></param> /// <returns></returns> public GameObject CreateMostGameobject(GameObject obj,Vector3 position,Quaternion rotation) { int objID = obj.GetInstanceID(); if (mostPool.ContainsKey(objID)) { if (mostPool[objID].Count > 0) { GameObject m_obj = mostPool[objID][0]; mostPool[objID].Remove(m_obj); m_obj.SetActive(true); m_obj.transform.position = position; m_obj.transform.rotation = rotation; return m_obj; } } //如果对象池中没有该游戏对象,实例化一个游戏对象 GameObject n_obj = GameObject.Instantiate(obj, position, rotation) as GameObject; return n_obj; } public void HideMostGameobject(GameObject obj) { int key = obj.GetInstanceID(); if (!mostPool.ContainsKey(key)) { mostPool.Add(key, new List<GameObject>()); } mostPool[key].Add(obj); obj.SetActive(false); } }