对象池
游戏开发过程中,为了防止对象的频繁创建和删除而引发系统的垃圾回收,从而导致游戏卡顿,因此会经常使用对象池。
首先看一下对象池对外暴露的接口定义
// 回收管理器
public interface IRecycleManager : IService
{
IRecyclePool Create(string poolType, IRecycleProcesser processer, IRecycleFactory factory = null);
IRecyclePool Find(string poolType);
}
// 对象池
public interface IRecyclePool
{
void Preload(string objectType, int count);
void PreloadAsync(string objectType, int count, Action callback);
T Pick<T>(string objectType);
void Drop(string objectType, object recycleObject);
}
// 对象处理器
public interface IRecycleProcesser
{
void RecoverObject(object recycleObject);
void ReclaimObject(object recycleObject);
}
// 对象工厂
public interface IRecycleFactory
{
object CreateObject(string objectType);
void CreateObjectAsync(string objectType, Action<object> handler);
void DestroyObject(object recycleObject);
}
这里的对象池存储的对象是:具有同样回收规则的对象。
每一个IRecycleProcesser就是一种回收规则,它实现了回收和重新使用的规则。对象池本身并不知道如何回收一个对象,它会在对象需要回收的时候将对象交给对应的IRecycleProcesser处理(ReclaimObject),在重新使用的时候也会交给IRecycleProcesser处理(RecoverObject)。
IRecycleFactory是对象的创建和销毁工厂,因为对象池本身并不理解存在其中的对象,因此如果希望对象池能够直接预加载一些对象,那么就需要关联特定的工厂类来实现如何创建和销毁对象。
样例:GameObject对象池
首先实现具体的回收规则类。
public class GameObjectProcesser : IRecycleProcesser
{
public void RecoverObject(object recycleObject)
{
var go = recycleObject as GameObject;
go.SetActive(true); // 显示该对象
}
public void ReclaimObject(object recycleObject)
{
var go = recycleObject as GameObject;
go.SetActive(false); // 隐藏该对象
}
}
可选:实现具体的对象工厂。因为在不需要对象池具有直接装载的对象的功能情况下并不需要实现。
public class GameObjectFactory : IRecycleFactory
{
public object CreateObject(string objectType)
{
// 获取资产管理服务
var assetManager = ServiceCenter.GetService<IAssetManager>();
// 同步创建
using (var asset = assetManager.Load(objectType, AssetType.Prefab))
{
return GameObject.Instantiate(asset.Cast<GameObject>());
}
}
public void CreateObjectAsync(string objectType, Action<object> handler)
{
var assetManager = ServiceCenter.GetService<IAssetManager>();
// 异步创建
assetManager.LoadAsync(objectType, AssetType.Prefab, asset =>
{
if (null != handler)
{
handler(GameObject.Instantiate(asset.Cast<GameObject>()));
}
asset.Dispose();
});
}
public void DestroyObject(object recycleObject)
{
var go = recycleObject as GameObject;
GameObject.Destroy(go);
}
}
接下来开始使用对象池
var recycleManager = ServiceCenter.GetService<IRecycleManager>();
var pool = recycleManager.Create("GameObject", new GameObjectProcesser(), new GameObjectFactory());
// 预创建100个Cube
pool.Preload("Prefab/Cube.prefab", 100);
// 获取一个Cube
var cube = pool.Pick<GameObject>("Prefab/Cube.prefab");
// 回收一个Cube
pool.Drop("Prefab/Cube.prefab", cube);