使用实体-组件-系统模式,我想将一些系统与事件联系起来。所以有些系统不应该循环运行,它们应该按需运行。
以Health系统为例,Death系统仅应在组件的生命值低于 1 时运行。
我想过有两种类型的系统。第一种是周期系统。每帧运行一次,例如渲染或移动系统。另一种类型是基于事件的系统。如前所述,健康与死亡之间存在联系。
首先,我创建了两种系统类型都使用的基本接口。
internal interface ISystem
{
List<Guid> EntityCache { get; } // Only relevant entities get stored in there
ComponentRequirements ComponentRequirements { get; } // the required components for this system
void InitComponentRequirements();
void InitComponentPools(EntityManager entityManager);
void UpdateCacheEntities(); // update all entities from the cache
void UpdateCacheEntity(Guid cacheEntityId); // update a single entity from the cache
}
此外,我创建了接口
internal interface IReactiveSystem : ISystem
{
// event based
}
和
internal interface IPeriodicSystem : ISystem
{
// runs in a loop
}
但我不确定它们是否有必要。使用没有问题
foreach (ISystem system in entityManager.Systems)
{
system.UpdateCacheEntities();
}
但如果不需要,我不想运行系统。
有两种类型的事件, aChangeEvent
和 a ExecuteEvent
。第一个在组件中的值发生更改时触发。当应该对特定实体进行某些操作时,会触发第二个。
如果你需要或想要你可以看看EntityManager
这ComponentRequirements
以及ECS的使用
一个示例系统将是这样的
internal class HealthSystem : IReactiveSystem
{
public HealthSystem(EntityManager entityManager)
{
InitComponentRequirements();
InitComponentPools(entityManager);
}
private Dictionary<Guid, HealthComponent> healthComponentPool;
public List<Guid> EntityCache { get; } = new List<Guid>();
public ComponentRequirements ComponentRequirements { get; } = new ComponentRequirements();
public void InitComponentRequirements()
{
ComponentRequirements.AddRequiredType<HealthComponent>();
}
public void InitComponentPools(EntityManager entityManager)
{
healthComponentPool = entityManager.GetComponentPoolByType<HealthComponent>();
}
public void UpdateCacheEntities()
{
for (int i = 0; i < EntityCache.Count; i++)
{
UpdateCacheEntity(EntityCache[i]);
}
}
public void UpdateCacheEntity(Guid cacheEntityId)
{
Health healthComponent = healthComponentPool[cacheEntityId];
healthComponent.Value += 10; // just some tests
// update UI
}
}
我怎样才能创建ChangeEvents
和ExecuteEvents
用于不同的系统?
编辑
如果更改事件正在侦听,或者如果执行事件正在侦听,是否有办法将事件委托添加到组件以在更改时为该实体运行特定系统?
通过提及ChangeEvent
,ExecuteEvent
我只是指事件代表。
目前我可以做这样的事情
internal class HealthSystem : IReactiveSystem
{
//… other stuff
IReactiveSystem deathSystem = entityManager.GetSystem<Death>(); // Get a system by its type
public void UpdateCacheEntity(Guid cacheEntityId)
{
// Change Health component
// Update UI
if(currentHealth < 1) // call the death system if the entity will be dead
{
deathSystem.UpdateCacheEntity(cacheEntityId);
}
}
}
但我希望通过使用事件委托使系统相互通信和共享数据来实现更好的架构。