C++ 如何在ECS模型中组织实体?
我有一个渲染系统,它迭代所有MeshDrawData组件,并对它们进行批处理和绘制。我的ECS实施只允许每个实体使用一种类型的组件 现在我想代表“运动员”乒乓球拍。我的OOP思维方式是这样的:C++ 如何在ECS模型中组织实体?,c++,entity,game-engine,entity-component-system,C++,Entity,Game Engine,Entity Component System,我有一个渲染系统,它迭代所有MeshDrawData组件,并对它们进行批处理和绘制。我的ECS实施只允许每个实体使用一种类型的组件 现在我想代表“运动员”乒乓球拍。我的OOP思维方式是这样的: Pseudocode: auto e = createEntity(); createSpriteComponent(e,...); // this creates a MeshDrawData internally for e entity. createColliderComponent(e,...)
Pseudocode:
auto e = createEntity();
createSpriteComponent(e,...); // this creates a MeshDrawData internally for e entity.
createColliderComponent(e,...);
这很好,但假设现在我也想渲染一条线。
如果我这样做:
Pseudocode:
auto e = createEntity();
createSpriteComponent(e,...); // this creates a MeshDrawData internally for the e entity.
createColliderComponent(e,...);
createLineComponent(e,...); // this creates a MeshDrawData internally for the e entity
在这里你可以看到问题。。我为实体e创建了两个MeshDrawData组件
鉴于我不真实的引擎背景,我创建了一个演员并向其添加组件。我一直认为ECS中的实体类似于演员,但我发现我完全错了
您如何组织您的实体,例如允许使用我前面提到的用例?实体究竟应该代表什么
可能的解决办法:
1:1实体:组件
是一个无聊的限制,但也是大多数ECS引擎的一个很好的限制
为了解决这些问题,我通常会执行以下操作之一:-
createLineComponent
中检查MeshDrawData
是否已存在,并执行一些自定义操作
我主要是这样做的:-
void createLineComponent(Entity e){
auto meshComponent=engine->addJustInCase<MeshDrawData>(e);
//^ if the component exists - just request the component, if not, create it
meshComponent->setFormat ...
}
void createLineComponent(实体e){
auto meshComponent=发动机->添加案例(e);
//^如果组件存在-只需请求组件,如果不存在,则创建它
网格组件->设置格式。。。
}
子关系系统的类型应非常具体 e、 g.
1:N碰撞器精灵
,而不是1:N实体
如果它开始变得一团糟-使用工厂模式来封装它
如果有人有任何(更好的)想法,请回答。我也想听听。谢谢你的回答。现在我在做你的方法。我用添加的最新组件覆盖MeshDrawData,该组件需要它。我不会选择这个作为正确答案,看看是否有人有其他想法。@FrameBuffer不错。如果您发现任何有用的东西或使用此方法完成游戏,请让我知道。:)我想得更多,我的结论是,你可以决定把你所有的状态都放在ecs中,或者与系统共享。我现在的方法是将所有状态放在组件中,只是为了保持一致。考虑到我决定为实体拥有的每个不同的“渲染器组件”创建一个子级。并在实体的“渲染器组件”中保存对实体的引用,以防您必须访问它。@FrameBuffer只是为了检查我的理解。你…吗。。。(1) 通过增强ECS核心引擎,允许1个实体拥有>1个
渲染器组件
?或者(2)减少/减少渲染器组件,使其不再是ECS组件,并手动管理它?还是别的什么。。。我只做了一次。它位于我的物理引擎(流形组件
)的性能关键区域。我“在一个实体中,每种类型只有一个组件”。从体系结构的角度来看,我所改变的是,带有线条渲染器和喷绘器的实体对我来说没有意义,因此我结束了您的第一(1)种方法(因为这是错误的)。例如,精灵是具有变换和精灵(将创建和处理自己的MeshDrawData)的实体。因此,具有精灵的角色将由具有子实体(精灵)的实体(玩家)表示。如果玩家想要画一条线,该线是另一个实体(transform,LineRenderer->MeshDrawData)