我想创建一个小的Entity-Component-System示例并创建一些组件,如
internal struct Position : IComponent
{
public int X { get; set; }
public int Y { get; set; }
}
和
internal struct MovementSpeed : IComponent
{
public int Value { get; set; }
}
每个组件都实现了一个当前为空的接口 IComponent
. 当系统循环遍历实体时,我希望快速找到相关组件 .
我想过创建一个Dictionary,它将组件类型作为键,将当前实体的组件作为值 .
我从 public Dictionary<Type, IComponent> Components { get; }
开始
我可以使用 myEntity.Components.Add(typeof(Movement), new Movement() as IComponent);
添加组件
但是我怎样才能返回一个组件?我创建了一个运动系统示例
internal class Movement : ISystem
{
public void Update()
{
foreach (Entity entity in EntityPool.activeEntities.Values) // Loop through all entities
{
Dictionary<Type, IComponent> components = entity.Components;
if (components.TryGetValue(typeof(Position), out Position positionComponent))
{
if (components.TryGetValue(typeof(MovementSpeed), out MovementSpeed movementSpeedComponent))
{
// TEST: move (1 * movementspeed) units
positionComponent.X += movementSpeedComponent.Value;
positionComponent.Y += movementSpeedComponent.Value;
}
}
}
}
}
if (components.TryGetValue(typeof(Position), out Position positionComponent))
崩溃,因为字典的值不返回所需类型本身的组件,它返回接口 .
我怎样才能使它工作?
(是的,我知道我可以使用ECS框架,但我想自己做这个用于学习目的)
2 回答
简短的回答:你做不到 . 如果字典的类型为
Dictionary<Type, IComponent>
,那么它将仅返回IComponent
.但是,您可以为此创建一个扩展方法:
并使用它:
如果插入IComponent类型的项目,则只能将该项目检索为IComponent . 如果您向Dictionary询问特定类型,则可以直接转换为该类型 .
使用linq,您可以非常有效地在列表中操作 . 也许这对你来说是更好的方式 . 这是一个例子: