【问题标题】:Give a specific global index to a given object based upon its type (C#)根据对象的类型为给定对象提供特定的全局索引(C#)
【发布时间】:2019-07-21 02:10:27
【问题描述】:

我一直在使用monogame 用C# 进行一些简单的游戏编程,目前我正在尝试从头开始创建一个基本的ECS。我意识到已经存在制作精良的 ECS 库,这更像是个人学习练习。

我现在的代码是这样的;

public class Entity{

    private bool active;
    IComponent[] Components;
    public Entity(){
        active = true;

    }

    public AddComponent(IComponent component){

    }


    public bool Active { get => active; set => active = value; }
}

由于 IComponent 是组件的接口,我想知道是否有一种方法可以在特定组件类型在运行时首次定义时为其定义全局数组索引?

例如;如果你有一个 Transform 组件和一个 CollisionComponent,那么当在运行时定义第一个 Transform 组件时,将为之后定义的每个 Transform 组件提供一个全局索引,碰撞器组件的行为方式相似,但索引号明显不同。

我正在寻找的 c++ 等价物是这样的:

inline ComponentID getNewComponentTypeID()
{
    static ComponentID lastID = 0u;
    return lastID++;
}

template <typename T>
inline ComponentID getComponentTypeID() noexcept
{
    static_assert(std::is_base_of<Component, T>::value, "");
    static ComponentID typeID = getNewComponentTypeID();
    return typeID;
}

【问题讨论】:

    标签: c# .net static components


    【解决方案1】:

    更新:替换为涉及静态属性初始化的更好解决方案。


    如果您需要跟踪组件类型,可以使用静态字段初始化来完成。应该是这样的:

    static class ComponentId
    {
        static int Max = 0;
        static class Index<T> where T: IComponent
        {
            public static int Value = Interlocked.Increment(ref Max);
        }
        static public int Get<T>() where T : IComponent => Index<T>.Value;
    }
    

    用法:

    var id1 = ComponentId.Get<TransformComponent>() // 1
    var id1 = ComponentId.Get<CollisionComponent>() // 2
    var id3 = ComponentId.Get<TransformComponent>() // again 1
    

    旧答案:对于需要在每个组件内部运行索引的情况,您可以执行以下操作:

    static class GlobalCounter<T> where T : IComponent
    {
        static int Value = 0;
        static public int GetNext() => Interlocked.Increment(ref Value);
    }
    

    您可以像这样使用它:GlobalCounter&lt;TransformComponent&gt;.GetNext()。每个T 都会有一个单独的Value

    【讨论】:

    • 您好,感谢您的回答,它并没有达到我想要的效果。如果我实现它并这样调用它: GlobalCounter.GetNext() GlobalCounter.GetNext() GlobalCounter.GetNext() 我会得到这些数字; 1, 2, 1 但所需的输出是 1, 1, 2。
    • @Simplexity:哦,我明白了,您需要一个 component 编号,而不是组件内的运行编号。我会更新答案。
    • @Simplexity:看看,我找到了更好的解决方案并更新了答案。
    猜你喜欢
    • 2018-06-19
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    • 2015-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-10
    相关资源
    最近更新 更多