gpt4 book ai didi

oop - 实体组件系统中的有限状态机实现

转载 作者:行者123 更新时间:2023-12-02 01:22:24 26 4
gpt4 key购买 nike

我想使用有限状态机来处理 Entity我的游戏中的状态。具体来说,就本文而言,我将引用 Player实体。

我的 Player将会有空闲、运行、跳跃、下降等状态……并且需要一些方法来管理这些状态以及它们之间的转换。在 OOP 环境中,最简单的解决方案是让每个状态都有自己的类,并有一个名为 handleInput 的方法。接受输入并确定是否应该发生状态更改。例如,在 IdleState如果 move_right 或 move_left 发生,状态将更改为新的 RunningState .这很容易也很有意义,因为状态的行为应该封装在状态中。

但是,当您在实体组件系统中使用 FSM 时,一切都会发生变化。状态不再是对象(因为这会违背组件系统的灵 active ),而是组件的不同排列。 JumpState可能有 JumpComponent 之类的组件, AirbornMovementComponent等...而 AttackState可能包含表示攻击的组件,例如 SwingComponent , DamageComponent , SwordComponent等... 这个想法是通过重新排列组件,可以创建新的状态。系统的工作是简单地分别处理这些组件,因为系统不关心状态,它们只关心单个组件。实际的 FSM 位于 FSMComponent由该实体持有。

这很有意义,除了在处理状态转换时。现在我有一个 InputSystem查找具有 InputComponent 的实体和 FSMComponent并尝试根据当前输入更新 FSM 的状态。但是,这并不是那么好用。

FSM 处理输入的最佳方式(在我看来)是让每个状态确定它想要如何处理输入以及如何根据该输入转换到新状态。这又回到了实现 FSM 的 OOP 方式,与 ECS 的设计背道而驰,其中组件只是数据包,系统负责所有逻辑。在 ECS 中,想法是让系统处理状态转换,但这会变得复杂,因为每个 FSM 可能有不同的状态转换条件。

您不能简单地在 InputSystem 中声明“如果输入向右移动,则将状态设置为运行”。这将是特定于玩家的,但可能不适用于 全部 实体。如果有一天我决定让一个敌人变得可控,那么适用于 Player 的输入不会是 Enemy 的相同输入.

我的问题 : 如何让我的 FSM 在 ECS 中足够通用和足够灵活,以允许状态转换的各种实现,而不必在系统本身中进行明确的 if/else 检查?

我是否以完全错误的方式接近这个?如果是这样,在实体组件系统中实现 FSM 的更好解决方案是什么?

最佳答案

只是重复@fallaciousreasoning 的帖子(及其后续评论)。

Ash 实际上有两个在不同级别运行的 FSM。

首先,FSM 在实体级别运行,当您从一种状态转换到另一种状态时,它通过更改实体上组件的组合来管理(实体)状态转换。

其次,FSM 在引擎级别运行,通过更改引擎执行的系统的组成来管理(引擎)状态转换。

它们结合起来形成了一个非常强大的 FSM。

诀窍是确定您需要使用哪种类型的过渡;一种是“数据”组合驱动转换,一种是“逻辑”组合驱动转换。

因此,有了这些新发现的知识,我们就可以推理它是如何工作的。

在更简单的改变组件组成的方法中,我们会使用一些“标记”组件,以及一些冗长的 switch 语句(或 if/else 检查)来处理实体状态的这些变化,最终导致臃肿的系统超过他们应该的。 Ash 的实体 FSM 对此进行了改进,并通过将给定的组件配置映射到标识符并提供可用于触发状态转换的管理器来避免那些冗长的 switch 语句(或 if/else 子句)。此管理器实例可以作为组件内的属性传递,也可以作为系统成员组合/注入(inject)。

或者,采用引擎 FSM 方法,我们将每个特定于状态的逻辑分解到它们自己的系统中,并根据给定的(引擎)状态将它们交换进出。这种方法并非没有缺点,因为缺少系统会影响与其关联的所有实体。但是,将系统专用于单个实体实例(例如,玩家角色)并不少见,因此这在正确的上下文中可以证明是有用的。想想它在某些情况下通过系统交换影响全局实体可能也是可取的。

( 注意:如果您的逻辑修改范围需要更窄,您可以将其限制在系统中而不涉及引擎 FMS。这可以通过在系统中实现状态模式来实现,系统可以通过委托(delegate)来改变其行为到基于状态的不同子系统。)

我已经看到一些 ECS 框架将系统组合标记为“阶段”,但它们从根本上充当 FSM,其中 ECS 引擎使用与给定阶段关联的不同系统集来处理实体。

最后,数据组合只是等式的一半;在尝试在 ECS 中实现 FSM 时,如何组合逻辑位(或 block )同样重要。

关于oop - 实体组件系统中的有限状态机实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39185133/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com