Unity3d 单例对象池
原创
题外话:今天遇到一个坑爹的事,新来了一个WIN10的电脑,但是Unity装完,任何IDE工具打开都无法识别命名空间,原来WIN10本来不带NET2.0,需要去控制面板--程序和功能---添加.net3.5
单例模式
初学者很容易搞晕,为啥有2种写法,这里顺带着写一下,不是本章的要点。
首先,是继承自MonoBehaviour的单例,需要使用U3D组件和功能可以用这种单例。理解U3D本身单例写法的机制就知道为啥要这么写了,第一个挂载脚本的对象,就是该单例,后面再怎么重复挂载是无效的。因为挂载的时候就实例化该类了。
public static ObjectPool instance; //单例 //U3D的单例机制,是第一个挂载脚本的对象,就是该单例,后面再怎么重复挂载是无效的。因为挂载的时候就实例化instance了。 void Awake() { instance = this; }
private static ObjectPool instance; //单例 public ObjectPool GetInstance() { if (instance == null) { instance = new ObjectPool(); } return instance; }
对象池
思路:重复创建大量物理和销毁物体,会大量消耗资源,比如:子弹,金币等等,对象池的作用就是创建完了不销毁,只能把它隐藏存入对象池,用一个列表保存数据,需要用的时候再取出来,同时激活它,并且移除列表,这样列表中剩下的就是隐藏可以使用的对象。因为可能有很多物体需要用对象池,所以把个物体的LIST列表存入一个字典。如果对象池中有100个对象,创建90个都是在对象池中激活,只有创建110,才会再新生成10个。
using UnityEngine; using System.Collections; using System.Collections.Generic; //U3D单例对象池 public class ObjectPool : MonoBehaviour { public static ObjectPool instance; //单例 public GameObject[] prefabObjects; //prefab数组 private Dictionary<string, List<GameObject>> pool = new Dictionary<string, List<GameObject>>(); //对象池字典 //U3D的单例机制,是第一个挂载脚本的对象,就是该单例,后面再怎么重复挂载是无效的。因为挂载的时候就实例化instance了。 void Awake() { instance = this; } //从池中获取 //正式项目最好用一个静态类来保存名字,防止出错 public GameObject GetOut(string GameObjectName, Vector3 vector3) { GameObject gameObject; //返回的gameObject //如果池中有 if (pool.ContainsKey(GameObjectName) && pool[GameObjectName].Count > 0) { //取池里的用 gameObject = pool[GameObjectName][0]; gameObject.SetActive(true); gameObject.transform.position = vector3; //取完移除 pool[GameObjectName].RemoveAt(0); } //如果没有 else { GameObject prefabObject = null; //要生成的prefabObject prefab数组中的物体名字要和传入的字符串一致 for (int i = 0; i < prefabObjects.Length; i++) { if (prefabObjects[i].name == GameObjectName) { prefabObject = prefabObjects[i]; } } //直接创建 gameObject = (GameObject)GameObject.Instantiate(prefabObject, vector3, Quaternion.identity); } return gameObject; } //存入对象池 public void SetIn(string GameObjectName,GameObject gameObject) { //池中没有 if (!pool.ContainsKey(GameObjectName)) { //新建池List pool.Add(GameObjectName, new List<GameObject>()); } //存入池 gameObject.SetActive(false); pool[GameObjectName].Add(gameObject); Debug.Log(pool[GameObjectName].Count); } //销毁对象池 public void DestroyPool(string GameObjectName) { if (pool.ContainsKey(GameObjectName)) { //删除对象 for (int i = 0; i< pool[GameObjectName].Count; i++) { Destroy(pool[GameObjectName][i]); } //移除列表 pool.Remove(GameObjectName); } } }
注意:使用的时候, 从对象池获取,什么地方都可以用,存入对象池这个方法最好在物体本身上,比如子弹上挂着一个,自己就把自身存入对象池。实际使用就用PoolManager 插件好了,据说很好用。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: Unity3D开发之对象池
- 下一篇: 【Unity编程】Unity3D-使用对象池高效管理内存