V3n*_*n0m 5 c++ architecture game-development game-engine entity-component-system
我已经写了一个ECS,但我对更新阶段有一些疑问。(在系统中)\n我读过很多文章,但没有找到此类问题的参考。
\n\n为了从 ECS 中获益(例如缓存友好),需要满足以下要求:
\n\n因此,每个系统中应用的逻辑都很好,并且在没有 \xe2\x80\x9cuser 代码\xe2\x80\x9d 时一切正常。\n但是,当我们处理用户代码时(例如用户可以将 C++ 代码附加到一个对象(如 Unity、Unreal)),问题就来了:
\n\n将逻辑添加到组件中会破坏纯 ECS 的优势(以缓存友好的方式对所有相同的组件执行相同的操作),因此恕我直言,这不是一个解决方案。
\n\n有人有解决办法吗?我想知道您在 ECS 实施中如何处理此类问题。
\n\n谢谢!
\n我和你有同样的疑问。
读完之后我对我的解决方案进行了建模(这是必须诚实阅读的内容):
Gamasutra:将面向数据的 ECS 与有状态的外部系统同步
一个可能的解决方案是设置一些有关读取和写入组件的规则。
我遵循的规则是,从组件数据中读取总是可以的,但是如果您必须将数据写入外部系统内的组件(它不是组件接口系统的一部分),则必须始终使用转换系统函数。
例如:
有一个像这样的转换组件:
struct transform {
glm::vec2 position = glm::vec2(0);
glm::vec2 scale = glm::vec2(1);
float rot_radians = 0.0f;
glm::mat3 ltp = glm::mat3(1);
glm::mat3 ltw = glm::mat3(1);
entt::entity parent = entt::null;
std::vector<entt::entity> children;
};
Run Code Online (Sandbox Code Playgroud)
我将定义一些系统来对其进行更改,如下所示:
void set_position(entt::registry& r, entt::entity e, glm::vec2 position);
void set_rotation(entt::registry& r, entt::entity e, float rot_radians);
void set_scale(entt::registry& r, entt::entity e, glm::vec2 scale);
void set_parent(entt::registry& r, entt::entity to, entt::entity parent = entt::null);
Run Code Online (Sandbox Code Playgroud)
在这些函数中,您可以自由地读取/写入变换组件数据。
我使用 ECS 的次数越多,我就越倾向于像用 C 语言编程一样思考。您拥有数据和更改该数据的函数。当然,您可以直接去更改组件数据,但我意识到不值得花时间试图避免这种情况,如果您在更新数据后需要更多东西的组件中执行此操作,那么这只是一个错误或糟糕的编程。
归档时间: |
|
查看次数: |
2576 次 |
最近记录: |