我想创建一个Entity-Component-System示例 . 我有像这样的组件
internal struct Position : IComponent
{
public int X { get; set; }
public int Y { get; set; }
}
和
internal struct Movementspeed : IComponent
{
public float Value { get; set; }
}
哪个实施
internal interface IComponent
{
}
循环遍历组件时,我希望尽可能快地找到它们 . 我想过创建一个Dictionary,它将组件类型作为键,组件作为值 .
internal class ComponentCollection
{
public ComponentCollection()
{
components = new Dictionary<Type, object>();
}
private Dictionary<Type, object> components;
public void AddComponent<T>(T component) // add a new component
{
Type componentType = typeof(T);
components.Add(componentType, component as IComponent);
}
public void RemoveComponent(Type componentType) // remove the component by type
{
components.Remove(componentType);
}
public bool TryGetComponent<T>(out T component) // get the specified component
{
try
{
Type componentType = typeof(T);
component = (T)components[componentType];
return true;
}
catch (Exception)
{
component = default(T);
return false;
}
}
}
有两个问题出现了 .
-
如果有人使用
float movementspeed
创建新的MovementspeedComponent并尝试添加它会怎么样?有两个浮点数会抛出一个重复的键异常 . 我只能添加实现IComponent
接口的自定义struct组件以防止重复 . -
当我尝试修改组件时,它们不会被引用修改
private static void Main(string[] args)
{
ComponentCollection components = new ComponentCollection();
components.AddComponent(new Position());
components.AddComponent(new Movementspeed());
if (components.TryGetComponent(out Position fooPosition))
{
fooPosition.X++;
Console.WriteLine(fooPosition.X); // prints 1
}
if (components.TryGetComponent(out Position barPosition))
{
Console.WriteLine(barPosition.X); // prints 0
}
Console.ReadLine();
}
有什么建议?
2 回答
我看到2个解决方案 . 要么使用类而不是结构,要么添加一些Update方法来更新字典中的结构
在完成更新结构后调用此方法:
如果您将使用类而不是结构,那么您的旧解决方案应该可行 .
当我们每种类型都有一个对象/集合时类型适用于键,否则
Dictionary<Type, object>
不合适,键应该是唯一的 .由于所有组件都是
struct
s这行代码:获取字典中包含的struct的副本 . 来自C# guide的报价: