我一直在使用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 Component和CollisionComponent,那么在定义运行时的第一个Transform Component时,将为之后定义的每个Transform Component提供一个全局索引,对撞机组件的行为类似,但索引号显然不同。>
与我正在寻找的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;
}
答案 0 :(得分:0)
更新:替换为涉及静态属性初始化的更好解决方案。
如果需要跟踪组件类型,则可以使用静态字段初始化来完成。就像这样:
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<TransformComponent>.GetNext()
。每个Value
都有一个单独的T
。