Unity游戏框架设计之缓存池管理器
简单介绍
在游戏运行的过程中,我们可能遇到这样的需求,即创建大量相同类型的敌人。在传统方法中,我们将对每一个敌人都重新创建,但这样是效率低且占据内存的。
为此我们可以这样做,所有敌人在创建时,都从敌人缓存池中取出敌人对象,当敌人死亡时,则将敌人放回到缓存池中。这样我们可以实现对敌人对象的复用,而不是频繁的创建和销毁敌人对象。
因此,我们可以基于享元模式,开发缓存池管理器来实现上述需求。缓存池管理器为所有相同类型的对象都创建一个缓存池,如果需要在游戏中创建对象,则从缓存池中取出对象,如果需要销毁一个对象,则将对象放回到缓存池中。利用缓存池管理器,我们避免频繁进行对象的创建和销毁,从而提高执行效率并降低内存占用。
代码设计
public class CachePoolManager : SingletonMono<CachePoolManager>
{
private readonly Dictionary<string, ObjectPool<GameObject>> _cachePoolSet = new();
private static int _defaultMaxCapacity;
public static void Initialize(int defaultMaxCapacity)
{
_defaultMaxCapacity = defaultMaxCapacity;
}
public void AddCachePool(string cachePoolName, GameObject asset, Transform father, int maxCapacity = default)
{
if (maxCapacity == default)
{
maxCapacity = _defaultMaxCapacity;
}
if (_cachePoolSet.ContainsKey(cachePoolName))
{
return;
}
_cachePoolSet.Add(cachePoolName, new(() => Instantiate(asset, father),
OnGetInstance, OnReleaseInstance, OnDestroyInstance, false, maxCapacity, maxCapacity)
);
}
public void RemoveCachePool(string cachePoolName)
{
if (!_cachePoolSet.ContainsKey(cachePoolName))
{
return;
}
_cachePoolSet[cachePoolName].Clear();
_cachePoolSet.Remove(cachePoolName);
}
public bool ContainsCachePool(string cachePoolName)
{
return _cachePoolSet.ContainsKey(cachePoolName);
}
public GameObject GetInstance(string cachePoolName)
{
if (!_cachePoolSet.ContainsKey(cachePoolName))
{
return default;
}
return _cachePoolSet[cachePoolName].Get();
}
public void PutInstance(string cachePoolName, GameObject instance)
{
if (!_cachePoolSet.ContainsKey(cachePoolName))
{
return;
}
_cachePoolSet[cachePoolName].Release(instance);
}
private void OnGetInstance(GameObject instance)
{
if (instance == null)
{
return;
}
instance.SetActive(true);
}
private void OnReleaseInstance(GameObject instance)
{
if (instance == null)
{
return;
}
instance.SetActive(false);
}
private void OnDestroyInstance(GameObject instance)
{
Destroy(instance);
}
}
代码说明
(一)基于 Unity 官方 API ObjectPool
实现。
(二)实现缓存池的创建、删除、查询操作,以及从缓存池中获取实例和放回实例的操作。
(三)每次从缓存池中获取对象时,都必须重置当前对象。比如,从缓存池中获取游戏对象后,如果需要为游戏对象添加脚本,则必须先判断脚本是否存在,如果存在则先删除此脚本,然后才重新添加脚本。
(四)每次场景被销毁后,都必须删除在当前场景创建的所有缓存池。防止下次重新进入此场景,从缓存池中取出游戏对象时发生空指针异常问题。发生的原因是,从缓存池中获取的游戏对象属于上一次被销毁的场景中的游戏对象。
后记
由于个人能力有限,文中不免存在疏漏之处,恳求大家斧正,一起交流,共同进步。
标签:缓存,cachePoolName,对象,return,instance,Unity,cachePoolSet,管理器 From: https://www.cnblogs.com/kkelin/p/18168289