当前位置:网站首页>复杂嵌套的对象池(4)——管理多类实例和多阶段实例的对象池
复杂嵌套的对象池(4)——管理多类实例和多阶段实例的对象池
2022-06-28 22:38:00 【永恒星】
【对象的分类】
在整个游戏过程中,对象非常多,可以根据一定的标准将对象分类:例如这些对象都属于UI、那些对象属于地形、还有些对象属于角色等等;有些对象只在第一阶段出现、有些只在第二阶段出现,有些只在第三阶段出现等等;有些对象属于某个剧情或任务中的;有些对象处于某个地点或范围等。
如果我们希望对游戏中的所有实例对象做一个管理,那么做一个复杂嵌套的超级对象池来管理,这个对象池内部如何嵌套的,也即如何将对象分类,是需要根据游戏,也即业务来做的。我们需要事先考虑好,这也反映出是否可以整体把握游戏。
在本文中,将对象做一个不同类别和不同阶段的分类,这里认为不同阶段里有不同类型的对象,也可以做不同类型的对象处于不同的阶段,代码基本上都大同小异,都是以前文的管理单个实例对象的对象池与管理多个实例的对象池为基础的。
【管理多类实例对象池的实现】
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace Cache
{
public enum ObjectType
{
Common = 0,
UI = 1,
Role = 2,
Effect = 3,
Terrain = 4,
Collider = 5,
Camera = 6,
Special
}
public class ObjectTypePool : ObjectPoolBase
{
private Cache<ObjectType, MultiObjectPool> _poolCache;//ObjectType本质是string,只不过数量少些用枚举,而不是MultiObjectPool中用string
private Dictionary<int, ObjectType> lentInstance2ObjectType = new Dictionary<int, ObjectType>();
private Dictionary<string, ObjectType> nameMap = new Dictionary<string, ObjectType>();
public ObjectTypePool(int capacity, string poolName, CacheWeedOutStrategy cacheWeedOutStrategy, Action<bool> onlendObjectOut = null, Action<bool> onRecycleObject = null) : base(capacity, poolName, onlendObjectOut, onRecycleObject)
{
poolCache = new Cache<ObjectType, MultiObjectPool>(cacheWeedOutStrategy, capacity, OnWeedOut);
_poolCache = poolCache as Cache<ObjectType, MultiObjectPool>;
foreach (ObjectType item in Enum.GetValues(typeof(ObjectType)))
{
nameMap.Add(item.ToString(), item);
}
}
public ObjectTypePool(PoolInfo poolInfo, Action<bool> onlendObjectOut = null, Action<bool> onRecycleObject = null) : base(poolInfo, onlendObjectOut, onRecycleObject)
{
if (poolInfo != null)
{
foreach (ObjectType item in Enum.GetValues(typeof(ObjectType)))
{
nameMap.Add(item.ToString(), item);
}
if (poolInfo.poolType == PoolType.ObjectType)
{
poolCache = new Cache<ObjectType, MultiObjectPool>(poolInfo.cacheWeedOutStrategy, poolInfo.capacity, OnWeedOut);
_poolCache = poolCache as Cache<ObjectType, MultiObjectPool>;
//初始化子对象池
foreach (var item in poolInfo.subPoolInfo)
{
var subPool = new MultiObjectPool(item, OnLendObjectOut, OnRecycleObject);
_poolCache.Put(nameMap[subPool.poolName], subPool);
TotalCapcity += subPool.TotalCapcity;
}
//使用默认的池子设置
for (int i = poolInfo.subPoolInfo.Count; i < poolInfo.subPoolCount; i++)
{
var subPool = new MultiObjectPool(poolInfo.defaultSubPoolInfo, OnLendObjectOut, OnRecycleObject);
_poolCache.Put(nameMap[subPool.poolName], subPool);
TotalCapcity += subPool.TotalCapcity;
}
}
}
}
public override GameObject LendObjectOut(string objectName, Transform parent = null, object[] extradata = null)
{
GameObject go = null;
if (string.IsNullOrEmpty(objectName))
return null;
MultiObjectPool multiObjectPool = null;
ObjectType objectType;//要将对象类型的参数传进来
if(Enum.TryParse<ObjectType>(extradata[0].ToString(),out objectType))
{
if (_poolCache.Get(objectType, out multiObjectPool))
{
go = multiObjectPool.LendObjectOut(objectName, parent);
}
}
if(go != null)
lentInstance2ObjectType[go.GetInstanceID()] = objectType;
return go;
}
public override bool RecycleObject(GameObject go)
{
if (go == null)
return false;
if (!lentInstance2ObjectType.ContainsKey(go.GetInstanceID()))
return false;
MultiObjectPool pool;
if (_poolCache.Get(lentInstance2ObjectType[go.GetInstanceID()], out pool))
{
if (pool.RecycleObject(go))
{
lentInstance2ObjectType.Remove(go.GetInstanceID());
return true;
}
}
return false;
}
private void OnWeedOut(MultiObjectPool multiObjectPool)
{
TotalCount -= multiObjectPool.TotalCount;
CachedCount -= multiObjectPool.CachedCount;
TotalCapcity -= multiObjectPool.TotalCapcity;
multiObjectPool.Dispose();
}
private void OnLendObjectOut(bool instantiated)
{
if (instantiated)
TotalCount++;
else
CachedCount--;
onlendObjectOut?.Invoke(instantiated);
}
private void OnRecycleObject(bool destroyed)
{
if (destroyed)
{
TotalCount--;
CachedCount--;
}
else
CachedCount++;
onRecycleObject?.Invoke(destroyed);
}
}
}
【管理多阶段实例的对象池】
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace Cache
{
public enum StageType
{
FirstStage = 1,
SecondStage,
ThirdStage,
FourthStage,
FifthStage,
}
public class StageObjectPool : ObjectPoolBase
{
private Cache<StageType, ObjectTypePool> _poolCache;
private Dictionary<int, StageType> lentInstance2StageType = new Dictionary<int, StageType>();
private Dictionary<string, StageType> nameMap = new Dictionary<string, StageType>();
public StageObjectPool(int capacity, string poolName, CacheWeedOutStrategy cacheWeedOutStrategy, Action<bool> onlendObjectOut = null, Action<bool> onRecycleObject = null) : base(capacity, poolName, onlendObjectOut, onRecycleObject)
{
poolCache = new Cache<StageType, ObjectTypePool>(cacheWeedOutStrategy, capacity, OnWeedOut);
_poolCache = poolCache as Cache<StageType, ObjectTypePool>;
foreach (StageType item in Enum.GetValues(typeof(StageType)))
{
nameMap.Add(item.ToString(), item);
}
}
public StageObjectPool(PoolInfo poolInfo, Action<bool> onlendObjectOut = null, Action<bool> onRecycleObject = null) : base(poolInfo, onlendObjectOut, onRecycleObject)
{
if (poolInfo != null)
{
foreach (StageType item in Enum.GetValues(typeof(StageType)))
{
nameMap.Add(item.ToString(), item);
}
if (poolInfo.poolType == PoolType.StageType)
{
poolCache = new Cache<StageType, ObjectTypePool>(poolInfo.cacheWeedOutStrategy, poolInfo.capacity, OnWeedOut);
_poolCache = poolCache as Cache<StageType, ObjectTypePool>;
//初始化子对象池
foreach (var item in poolInfo.subPoolInfo)
{
var subPool = new ObjectTypePool(item, OnLendObjectOut, OnRecycleObject);
_poolCache.Put(nameMap[subPool.poolName], subPool);
TotalCapcity += subPool.TotalCapcity;
}
//使用默认的池子设置
for (int i = poolInfo.subPoolInfo.Count; i < poolInfo.subPoolCount; i++)
{
var subPool = new ObjectTypePool(poolInfo.defaultSubPoolInfo, OnLendObjectOut, OnRecycleObject);
_poolCache.Put(nameMap[subPool.poolName], subPool);
TotalCapcity += subPool.TotalCapcity;
}
}
}
}
public override int Capacity()
{
return poolCache.Capacity();
}
public override int Count()
{
return poolCache.Count();
}
public override GameObject LendObjectOut(string objectName, Transform parent = null, object[] extradata = null)
{
GameObject go = null;
if (string.IsNullOrEmpty(objectName))
return null;
StageType stageType;//要将阶段类型和对象类型也传进来
if (Enum.TryParse<StageType>(extradata[0].ToString(), out stageType))
{
ObjectType objectType;
if(Enum.TryParse<ObjectType>(extradata[0].ToString(), out objectType))
{
ObjectTypePool objectTypePool = null;
if (_poolCache.Get(stageType, out objectTypePool))
{
go = objectTypePool.LendObjectOut(objectName, parent,objectType);
}
}
}
if (go != null)
lentInstance2StageType[go.GetInstanceID()] = stageType;
return go;
}
public override bool RecycleObject(GameObject go)
{
if (go == null)
return false;
if (!lentInstance2StageType.ContainsKey(go.GetInstanceID()))
return false;
ObjectTypePool pool;
if (_poolCache.Get(lentInstance2StageType[go.GetInstanceID()], out pool))
{
if (pool.RecycleObject(go))
{
lentInstance2StageType.Remove(go.GetInstanceID());
return true;
}
}
return false;
}
private void OnWeedOut(ObjectTypePool objectTypePool)
{
TotalCount -= objectTypePool.TotalCount;
CachedCount -= objectTypePool.CachedCount;
TotalCapcity -= objectTypePool.TotalCapcity;
objectTypePool.Dispose();
}
private void OnLendObjectOut(bool instantiated)
{
if (instantiated)
TotalCount++;
else
CachedCount--;
onlendObjectOut?.Invoke(instantiated);
}
private void OnRecycleObject(bool destroyed)
{
if (destroyed)
{
TotalCount--;
CachedCount--;
}
else
CachedCount++;
onRecycleObject?.Invoke(destroyed);
}
}
}
【需要管理类吗】
现在有很多类型的对象池,正如我们需要用对象池去管理很多实例一般,我们需要一个对象池管理类来管理很多的对象池。回顾一下,本文的多类实例的对象池和对阶段实例的对象池也是对一系列相同的对象进行了管理。
边栏推荐
- What does project management really manage?
- 在线文本过滤小于指定长度工具
- Mono 的执行流程
- Powerful open source API interface visual management platform Yapi
- 基于graph-linked embedding的多组学单细胞数据整合与调控推理
- 稳!上千微服务如何快速接入 Zadig(Helm Chart 篇)
- What is the difference between WMS warehouse management system and ERP
- torch.nn.Transformer导入失败
- 强大的开源API接口可视化管理平台-YApi
- go语言插件平台的实现思路
猜你喜欢

DBNN实验进展

Multiomics single cell data integration and regulatory reasoning based on graph linked embedding

Interpretation of papers (DCN) towards k-means-friendly spaces: simultaneous deep learning and clustering

What is the prospect of VR panoramic production?

爱数SMART 2022峰会开启,分享数据战略与建设数据驱动型组织方法论

00 後雲原生工程師:用 Zadig 為思創科技(廣州公交)研發開源節流

论文解读(DCN)《Towards K-means-friendly Spaces: Simultaneous Deep Learning and Clustering》

穿越过后,她说多元宇宙真的存在

This simple little function saves 213 hours for our production research team in half a year

How to analyze the trend chart of London gold market with the moving average
随机推荐
【Try to Hack】nmap
Panxiaoming, senior vice president of IC nansha|amd and President of Greater China: process, architecture and platform optimization break through the computing boundary
A password error occurred when docker downloaded the MySQL image to create a database link
In order to control the risks, how to choose a franchise company?
长投学堂帮忙开证券账户是安全靠谱的吗?个人如何开
Oracle set password complexity and timeout exit function
基于graph-linked embedding的多组学单细胞数据整合与调控推理
一文搞懂shell脚本
What is low code development?
分享im即时通讯开发之WebSocket:概念、原理、易错常识
IC Nansha|AMD高级副总裁、大中华区总裁潘晓明:制程、架构、平台优化突破计算边界
2022-06-28: what does the following golang code output? A:true; B:false; C:panic; D: Compilation failed. package main import “fmt“ func main() {
利用Redis实现点赞功能的示例代码
超级工厂里的生意图鉴
C#/VB.NET 将PDF转为Excel
时间序列预测系列文章总结(代码使用方法)
Zadig officially launched vs code plug-in, making local development more efficient
How to advance data analysis from 1 to 10?
Linux Installation mysql5.7 (centos7.6) tutorial
Realization of 2D code generation in micro build low code