最近闲来无事,利用空余时间写了一个对象池。
首先,什么是对象池呢?
举一个例子。在我们玩FPS类型的游戏的时候(这里就举例《守望先锋吧》),点击鼠标左键便会进行射击,会“创建”出子弹。而此时,随着游戏的不断进行(如果一局进行了20分钟),便会“创建”成千上万颗子弹,如果我们每点击一下鼠标就New一个对象,我想,不管是多牛B的电脑恐怕也吃不消。所以,我们需要一个对象池来进行对象的管理。
图示:
A.接下来,我们来实现代码。
1.创建对象池脚本 “GameObjectManager.cs”
using UnityEngine; using System.Collections; using System.Collections.Generic; //存储对象的名字 public class GameObjectName { public static string g_ButtleName = "g_Buttle"; } //碰撞标签 public class Tags { public static string g_Wall = "Wall"; } public class GameObjectManager : MonoBehaviour { //简单单例:“粗制滥造型” public static GameObjectManager _Instance; //字典 public Dictionary<string, List<GameObject>> m_dic; void Awake() { _Instance = this; m_dic = new Dictionary<string, List<GameObject>>(); } void Start () { //1.初始化子弹的表 Debug.Log("初始化 子弹"); GameObject go = GameObject.Instantiate(Resources.Load("Prefabs/g_Buttle")) as GameObject; Init(GameObjectName.g_ButtleName, go); } //初始化对象池里面的某个对象 public void Init(string _name, GameObject go) { List<GameObject> m_list = new List<GameObject>(); m_list.Add(go); m_dic.Add(_name, m_list); go.SetActive(false); } //得到对象 public GameObject GetGameObjectInDic(string _name) { string str = "Prefabs/" + _name; //如果存在 if (m_dic.ContainsKey(_name)) { for (int i = 0; i < m_dic[_name].Count; ++i) { if (!m_dic[_name][i].activeSelf) { m_dic[_name][i].SetActive(true); return m_dic[_name][i]; } } GameObject go1 = GameObject.Instantiate(Resources.Load(str)) as GameObject; m_dic[_name].Add(go1); return go1; } GameObject go2 = GameObject.Instantiate(Resources.Load(str)) as GameObject; Init(_name, go2); return go2; } }
2.让子弹运行起来,在子弹的Prefab中绑定该脚本,ButtleRun.cs
using UnityEngine; using System.Collections; public class ButtleRun : MonoBehaviour { //子弹的运行速度 private float m_buttleSpeed = 10.0f; void Start () { } // Update is called once per frame void Update () { //子弹跑起来 GameButtleRun(); } void OnTriggerEnter(Collider other) { Debug.Log("触碰"); if (other.gameObject.CompareTag(Tags.g_Wall)) { gameObject.SetActive(false); } } void GameButtleRun() { transform.position += transform.forward * m_buttleSpeed * Time.deltaTime; } }
3.创建子弹的脚本,点击鼠标左键,生成子弹 CreateButtle
using UnityEngine; using System.Collections; public class CreateButtle : MonoBehaviour { void Start () { } // Update is called once per frame void Update () { if (Input.GetMouseButtonDown(0)) { Debug.Log("创建子弹"); //得到子弹 GameObject buttle = GameObjectManager._Instance.GetGameObjectInDic(GameObjectName.g_ButtleName); buttle.transform.position = GameObject.Find("Gun/Position").transform.position; //buttle.transform.position += GameObjectManager._Instance.m_dic[GameObjectName.g_ButtleName][i].transform.forward * buttleSpeed * Time.deltaTime; } } }
B.Unity场景中的效果
1.点击鼠标左键,创建子弹
2.碰撞到墙面,子弹“消失”