实体组件系统:将渲染逻辑放在哪里

Entity Component System: Where to put rendering logic

我目前正在学习 "Entity Component System"。 在阅读了许多教程和论坛帖子后,我仍然想知道渲染逻辑应该去哪里。我不是在谈论实际的 OpenGL/DirectX-Rendering 代码,例如,获取精灵并渲染它。我的意思是决定 渲染哪个 精灵的逻辑。

可见实体需要三个方面:

  1. 评估 AI(改变位置、状态……)
  2. 正在评估渲染状态。例如当实体行走、攀爬、被击中时使用哪个精灵循环,...
  3. 实际渲染精灵

大多数教程建议使用类似 AISystem (1.) 的逻辑和 RenderSystem (3.) 来显示在 RenderComponent 中定义的精灵(循环)。他们没有说的是 RenderComponent 更新的地方。 据我了解,只是将 (2.) 放入 (1.),从而将角色逻辑与渲染逻辑混合,将是糟糕的设计。

直接的解决方案是为每个敌人添加一个特定的渲染逻辑系统。因此,例如对于 Gumba,我可以添加一个 GumbaLogicSystem、一个 GumbaRenderLogicSystem 和一个用于实际渲染的通用 SpriteRenderSystem,所有基于 sprite 的实体都使用它。然而,这意味着为每个实体类型创建两个组件*和两个系统,这似乎不是一个好的解决方案。

有没有一个很好的解决方案,在保持系统数量少的情况下,将角色逻辑和渲染逻辑分开?

谢谢

(* = 在一个简单的方法中,系统根据其组件处理实体。为了让 GumbaRenderLogicSystem 在实体上工作,它需要一个 GumbaRenderingLogicComponent 才能被该系统识别。相同的是字符逻辑为真。)

Edit1: 我知道 ECS 是一种抽象模式。我的问题针对如何保持系统数量少的最佳实践。我的例子是出于游戏编程的动机,但不限于这个领域。让我用一个更抽象的例子来解释:

想象一下我有一些可见的实体。在基于层次结构的体系结构中,我会有类似的东西:

在 ECS 中,我需要一大堆新的 classes:

有什么方法可以减少需要引入的新系统的数量?一种解决方案可能是添加 "agents" 或 "behavior objects":通用 RenderingComponent 附加了一些 "RenderingAgent" class 的实例,该实例具有一个名为 "Update" 的方法在渲染系统中。所以从技术上讲,组件本身不包含逻辑。不过,我担心这可能设计过度了。

经过一段时间的思考和多次讨论后,我意识到我的思维方式可能是错误的。我所描述的内容实际上适用于普通 ECS 方法。

防止系统和组件爆炸式增长的唯一方法是对游戏元素进行适当的抽象,这样渲染的各种需求就可以描述,而不是被编程。

我的意思是,比如一个sprite引擎必须允许足够的抽象,你可以只通过存储在由渲染系统评估的渲染组件中的描述来表达各种动画和状态。您还需要做的是将您的解决方案适当地拆分成可重复使用的部分。

通过这种方式,ECS 比其他模式更能迫使您真正思考一个好的架构。