GKEntity /组件更新周期最佳做法

时间:2017-01-15 19:23:11

标签: sprite-kit swift3 gameplay-kit

主题

我的问题是关于更新周期的划分,结合Apple的框架以尊重关于该主题的典型模式和良好实践,因为大多数文档和示例代码尚未适应Swift(或至少我无处可寻。)

有很多方法可以管理GameplayKit中的更新周期,我不太清楚将所有内容组合在一起的好方法。

元素

首先:实体/组件中的每个类(GKComponentGKEntity(子)类都有一个update()方法,您可以覆盖该方法来执行每帧更新。这必须来自当前GKScene / SKScene的更新周期。

然后,您可以使用GKComponentSystem来启动已添加到其中的给定类型的每个组件的update()方法。我明白了这一点,非常方便。

但我也想使用状态机系统,它也有自己的更新周期......结合所有让我困惑的事情。

我的情况

如果我有一个GKEntity的子类,其初始化时创建了一个GKStateMachine的实例。状态机有一些状态(暂时:'Spawn','Normal','Stunned'和'Death'。

State cycle

现在,我正在用我的GKEntity子类创建一个大的“cookie cutter”,并创建它将在初始化期间使用的所有组件。但它变得非常不切实际。例如,我有一个MovementComponent,它是GKAgent2D的子类。我创建了一个管理实体创建的单例,因此在创建实例后,if循环遍历所有实体的组件并将它们添加到相关的GKComponentSystems。单例有一个自己的update()方法,更新将调用传递给GKComponentSystems。我使用的某些组件不需要按帧更新,因此没有为它们创建GKComponentSystem,我会根据需要手动更新它们。

如果我回到我的实体,因为我一次创建所有内容并使用GKComponentSystems来更新组件,我的组件的更新方法加载了guardif-let语句,因为我需要访问实体的状态机,检查它是否是实体可以移动的状态(正常状态)并执行其操作或转义函数。这在我看来效率不高:移动组件在产生,震惊或死亡时不需要更新。

最重要的是,由于我的更新方法为空,因此我使用GKStateMachine完全过度杀戮:无论如何,组件都会被GKComponentSystem更新。

我的想法

  1. 完全删除GKComponentSystems并简单地遍历我的所有实体(如果需要,可以在某些时候将它们排序在不同的集合中)并调用它们的update()方法。将更新分派给状态机,然后更新状态中涉及的组件。

  2. 保留GKComponentSystems并使用状态机来处理组件,例如在进入和退出正常状态时从组件系统中添加和删除MovementComponent

  3. 选项1 很简单,但从长远来看,当我的结构变得更复杂时可能会导致问题,因为某些组件可能需要在其他组件之前更新。让每个实体更新自己的组件会分散更新过程。

    选项2 在某种程度上也会让人感到困惑,但我最担心的是创建/删除组件。我是否只将它们从GKComponentSystems中取出,还是将它们完全从实体中取出?最有效的方法是什么?

    实际问题

    我的哪一个选项最好?是否有更好的方法。

1 个答案:

答案 0 :(得分:1)

如果您使用GKComponentSystem执行更新,那么我就是这样做的。我认为组件每帧只应更新一次。

从您的问题中不清楚您需要对StateMachines做什么,但没有理由不让它们直接涉及您的GKEntity或包含在GKComponent之内DemoBots IntelligenceComponent