GKEntity/组件更新周期最佳实践

Bad*_*ger 7 sprite-kit gameplay-kit swift3

主题

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

在 GameplayKit 中管理更新周期的方法太多了,我不太确定什么是组合所有内容的好方法。

要素

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

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

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

我的情况

在我有一个在初始化时创建GKEntity的实例的子类的情况下GKStateMachine。状态机有几个状态(目前:“Spawn”、“Normal”、“Stunned”和“Death”。

状态循环

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

如果我回到我的实体,因为我一次创建所有内容并用于GKComponentSystems更新组件,我的组件的更新方法加载了guardif-let语句,因为我需要访问实体的状态机,检查它是否是实体可以移动的状态(正常状态)并做它的事情或逃避功能。在我看来,这并不高效:移动组件在生成、眩晕或死亡时不需要更新。

最重要的是,它使我使用GKStateMachine完全矫枉过正,因为我的更新方法是空的:GKComponentSystem无论如何,组件都会被更新。

我的想法

  1. 掉落GKComponentSystems通过我所有的实体(在某些时候也许某种他们在不同的藏品如果需要的话)完全和简单的循环,并呼吁他们的update()方法。将更新分派给状态机,状态机又会更新该状态中涉及的组件。

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

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

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

实际问题

我的哪一种选择是最好的?有没有更好的方法来做到这一点。

Mar*_*ord 3

如果您用于GKComponentSystem执行更新,那么我会这样做。我认为组件每帧应该只更新一次。

从您的问题中不清楚您需要对 StateMachines 做什么,但没有理由不让它们直接参与您的GKEntity或包含在GKComponentDemoBots IntelligenceComponent这样的组件中。