Unity程序优化之对象池
对于做程序的朋友来说优化是一个避免不了的话题,对于程序的优化可以从两个方面来入手,一个是CPU方面的优化,一个是GPU的优化。对于CPU与GPU的作用简单理解的话你可以暂时当做CUP是处理计算的、GPU是处理渲染的,例如程序中的一些计算啊逻辑处理啊都是有CPU来处理的,,我们程序的显示啊,特效等一切看到的东西都是GPU来处理的。当然他们的关系不单单如此,扯远了哈,我们这篇博客主要讲CPU优化方面的对象池技术。对象池大家应该都听说过,它主要应用于处理需要大量重复利用的资源的,因为如果有很多资源如果我们需要重复利用的话,如果我们每次都是创建销毁创建销毁,是很耗计算机性能的,我们完全可以把不用的资源暂时禁用掉SetActive(false)而不是销毁,当我们需要再次使用时就把它激活重复利用。
对象池的原理很简单,就是首先我们要创建一个池子,可以用字典也可以用栈,取决于你自己数据结构学的怎么样了,你觉得怎么高效怎么来,然后需要一个从池子里取东西的方法和一个回收东西到池子的方法,我们暂时不用的资源就可以通过回收的方法将其放到池子里暂时禁用,当我们再次需要利用时就将其从池子里取出来,重新激活使用就行了,一个简单的对象池脚本如下,这是一个单例脚本,我池子用的是字典结构,通过物品的名字来索引资源,使用时直接调用取资源的方法GetGameFromPool()和回收资源的方法RecycleToPool(GameObject gam)就好。
/*********************************** * Description:对象池 * Mountpoint:这是一个单例类,无需挂载 * Date:2019.05.25 * Version:版本 * Author:LJF ***********************************/ using System.Collections; using System.Collections.Generic; using UnityEngine; namespace LJF { //规范命名、合理封装、限制访问修饰符 public class ObjectPool { //构造函数 private ObjectPool() { pool = new Dictionary<string, List<GameObject>>(); prefabs = new Dictionary<string, GameObject>(); } //单例 private static ObjectPool instance; //获取单例 public static ObjectPool Instance { get { if (instance == null) { instance = new ObjectPool(); } return instance; } } //对象池 private Dictionary<string, List<GameObject>> pool; //预设体 private Dictionary<string, GameObject> prefabs; /// <summary> /// 从池子中获取GameObject /// </summary> /// <param name="objectname">物体的路径(名字)</param> /// <returns></returns> public GameObject GetGameFromPool(string objectname) { GameObject g = null; if (pool.ContainsKey(objectname)) { if (pool[objectname].Count > 0) { g = pool[objectname][0]; g.SetActive(true); pool[objectname].Remove(g); return g; } } GameObject t = null; if (prefabs.ContainsKey(objectname)) { t = prefabs[objectname]; } else { //1,从Resources读取 t = Resources.Load<GameObject>("Prefabs/" + objectname); //2,从AssetBundle读取 //AssetBundle ab = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/AssetBundle/all.ab");//有文件生成资源包 //t = ab.LoadAsset<GameObject>(objectname); prefabs.Add(objectname, t); } t = UnityEngine.Object.Instantiate(t); t.SetActive(true); t.name = objectname; return t; } /// <summary> /// 回收物体到池子中 /// </summary> /// <param name="gam"></param> public void RecycleToPool(GameObject gam) { gam.SetActive(false); if (pool.ContainsKey(gam.name)) { pool[gam.name].Add(gam); } else { pool.Add(gam.name, new List<GameObject>() { gam }); } } } }