【发布时间】:2019-05-10 19:22:30
【问题描述】:
我想创建一个小型实体组件系统示例并创建一些组件,例如
internal struct Position : IComponent
{
public int X { get; set; }
public int Y { get; set; }
}
和
internal struct MovementSpeed : IComponent
{
public int Value { get; set; }
}
每个组件都实现了一个当前为空的接口IComponent。当系统循环遍历实体时,我想快速找到相关组件。
我想过创建一个字典,将组件类型作为键,将当前实体的组件作为值。
我从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 框架,但出于学习目的我想自己做)
【问题讨论】:
-
您需要使用反射来查找并获取指定成员的值。更好的方法是将成员放在您的界面中。我不确定我明白你在做什么,但这就是使用接口的目的。
-
为什么嵌套了
ifs? -
@JonathanWood 你介意再解释一下吗?
-
@Fabjan 因为这个系统应该只更新附有位置和移动速度组件的实体
-
从字典中以
IComponent检索它,然后将其转换为Position。因为你只是拉Positions,所以演员应该总是成功(尽管我会使用is或as来确保和防止InvalidCastException)
标签: c# entity-component-system