游戏中,实例化是比较耗时的操作,在生成子弹、敌人等需要大量复制的对象时,如果都直接实例化,将增加许多没必要的内存和时间开销,因此我们应该针对这些对象使用对象池。
直接上对象池代码:
1 using UnityEngine; 2 using System.Collections.Generic; 3 using System.Collections; 4 5 public class ObjectPools : MonoBehaviour 6 { 7 private GameObject result; //对象池要返回的当前对象 8 private Dictionary<string, List<GameObject>> poolList;//对象池 9 private string keyTag; //对象池字典Key 10 private const float recycleTime = 5f; //回收时间 11 12 #region Singleton 13 private static ObjectPools defautPools; 14 public static ObjectPools DefaultPools { 15 get { 16 return defautPools; 17 } 18 } 19 #endregion 20 21 void Awake() 22 { 23 poolList = new Dictionary<string, List<GameObject>>(); 24 defautPools = this; 25 } 26 27 /// <summary> 28 /// 从对象池实例化 29 /// </summary> 30 public GameObject MyInstantiate(GameObject prefab, Vector3 position, Quaternion rotation) 31 { 32 keyTag = prefab.tag; 33 //如有某个小集合的Key,并且小集合内元素数量大于0 34 if(poolList.ContainsKey(keyTag) && poolList[keyTag].Count > 0) //弹夹里面有子弹 35 { 36 result = (poolList[keyTag])[0]; //取弹夹里面的第一个子弹 37 poolList[keyTag].Remove(result); //从弹夹里面移除子弹 38 result.transform.position = position; 39 result.transform.rotation = rotation; 40 } 41 else 42 { 43 //如果元素不存在,添加元素 44 if(!poolList.ContainsKey(keyTag)) 45 { 46 poolList.Add(keyTag, new List<GameObject>()); 47 } 48 result = (GameObject)Instantiate(prefab, position, rotation); 49 } 50 //开启回收协程方法 51 StartCoroutine(AutoRecycle(result)); 52 result.SetActive(true); 53 return result; 54 } 55 56 /// <summary> 57 /// 协程方法回收 58 /// </summary> 59 private IEnumerator AutoRecycle(GameObject bullet) 60 { 61 yield return new WaitForSeconds(recycleTime); 62 poolList[bullet.tag].Add(bullet); 63 bullet.SetActive(false); 64 } 65 }