1

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つの問題が発生します。

  1. 誰かが を使用して新しい MovementspeedComponent を作成し、float movementspeedそれを追加しようとした場合はどうなりますか? フロートが 2 つあると、重複キー例外がスローされます。IComponent重複を防ぐためにインターフェイスを実装するカスタム構造体コンポーネントしか追加できませんでした。

  2. コンポーネントを変更しようとすると、参照によって変更されません

    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();
    }
    

助言がありますか?

4

2 に答える 2