废话不多说先上流程图

目前项目里面大多数用的对象池一般都是类对象池或者物体对象池
我参加的面试里面经常会问到如何去优化string的问题,string了几次创建了多少个对象,我们一般通常做法就是用stringbuilder来优化,它其实本身也是一个类,每一次用的时候也得new,如果用多的话也new的特别多,那么类的对象池在这里就用的特别多了。
对象池的思想就是预先创建,提供初始化接口,有创建好的调用初始化就直接用,没有的话我再去创建。
类的对象池
在这里每个类对象区分我用的是hash码来识别,而这个类我用Queue队列去存储

key为hashcode,value用队列去存储;
作为一个池那么他需要提供出来(dequeue)和进去(enqueue)接口!


这两个接口写完之后,我们需要考虑如何释放,那么在提供一个clear清空接口,在切换场景时或者其他需要释放时调用。

到这里三个接口就写完了,但是类对象不如物体对象能够直接到看到,类对象在内存里看不到,我们需要把它在编辑器上能够显示出来。
创建Editor文件下,在文件夹下创建PoolEditor显示脚本;
这个太长了,我就不截图了,直接上代码。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace JIANING
{
[CustomEditor(typeof(PoolComponent), true)]
public class PoolComponentInsprctor : Editor
{
//释放间隔属性
private SerializedProperty m_ClearInterval = null;
//释放间隔属性
private SerializedProperty m_GameObjectPoolGroups = null;
public override void OnInspectorGUI()
{
serializedObject.Update();
PoolComponent component = base.target as PoolComponent;
int clearInterval = (int)EditorGUILayout.Slider("清空类对象池间隔", m_ClearInterval.intValue, 10, 1800);
if (clearInterval != m_ClearInterval.intValue)
{
component.m_ClearInterval = clearInterval;
}
else
{
m_ClearInterval.intValue = clearInterval;
}
GUILayout.BeginHorizontal("box");
GUILayout.Label("类名");
GUILayout.Label("池中数量", GUILayout.Width(50));
GUILayout.Label("常驻数量", GUILayout.Width(50));
GUILayout.EndHorizontal();
if (component != null
&& component.PoolManager != null
)
{
foreach (var item in component.PoolManager.ClassObjectPool.InspectorDic)
{
GUILayout.BeginHorizontal("box");
GUILayout.Label(item.Key.Name);
GUILayout.Label(item.Value.ToString(), GUILayout.Width(50));
int key = item.Key.GetHashCode();
byte resideCount;
component.PoolManager.ClassObjectPool.ClassObjectCount.TryGetValue(key, out resideCount);
GUILayout.Label(resideCount.ToString(), GUILayout.Width(50));
GUILayout.EndHorizontal();
}
}
EditorGUILayout.PropertyField(m_GameObjectPoolGroups,true);
serializedObject.ApplyModifiedProperties();
//重绘
Repaint();
}
private void OnEnable()
{
//建立属性关系
m_ClearInterval = serializedObject.FindProperty("m_ClearInterval");
m_GameObjectPoolGroups = serializedObject.FindProperty("m_GameObjectPoolGroups");
serializedObject.ApplyModifiedProperties();
}
}
}

游戏物体对象池
游戏物体对象池我们利用PoolManager插件,然后进行封装为我们想要的;

这里我们用byte作为池的key,因为一个项目也不可能用成百上千的池对象。



游戏物体对象和类对象思想上相同,但是在处理上面不同。
到这里对象池组件就写完了,具体代码可访问github。