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
{
}
コンポーネントをループするときは、できるだけ早く見つけたいと思っています。コンポーネントの型をキーに、コンポーネントを値に取るディクショナリを作成することを考えました。
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;
}
}
}
2つの問題が発生します。
誰かが を使用して新しい MovementspeedComponent を作成し、
float movementspeed
それを追加しようとした場合はどうなりますか? フロートが 2 つあると、重複キー例外がスローされます。IComponent
重複を防ぐためにインターフェイスを実装するカスタム構造体コンポーネントしか追加できませんでした。コンポーネントを変更しようとすると、参照によって変更されません
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(); }
助言がありますか?