阶段

所有要由 Bevy 运行的系统都包含在阶段中。每一帧更新,Bevy 都按顺序执行每个阶段。在每个阶段中,Bevy 的调度算法通过使用多个 CPU 核,可以并行地运行许多系统,以获得良好的性能。

阶段之间的边界是同一阶段内所有系统的强制同步点。它们确保前一阶段的所有系统在下一阶段的任何系统开始之前全部已经执行结束,所以有这么一个时间点,没有任系统处于执行状态。

这使得安全地使用命令成为可能。任何在系统中使用 命令 进行的操作都会在该阶段结束时应用生效。

在内部,Bevy 至少有这些内置的阶段:

  • 在主应用程序(CoreStage)中:FirstPreUpdateUpdatePostUpdateLast
  • 在渲染子程序(RenderStage)中:ExtractPrepareQueuePhaseSortRenderCleanup

默认情况下,当你添加你的系统时,它们会被添加到 CoreStage::Update

Bevy 的内部系统存在于其他阶段,相对于你的游戏逻辑,以确保它们执行顺序正确。

如果你想在 Bevy 的任何一个内部阶段添加你自己的系统,你需要谨防与 Bevy 自己的内部系统发生潜在的意外干扰。记住:Bevy 的内部系统是用普通的系统和 ECS 实现的,就像你自己的系统一样!

你可以添加你自己的附加阶段。例如,如果我们希望在我们的游戏逻辑之后运行我们的调试系统:

    fn main() {
        // label for our debug stage
        static DEBUG: &str = "debug";

        App::new()
            .add_plugins(DefaultPlugins)

            // add DEBUG stage after Bevy's Update
            // also make it single-threaded
            .add_stage_after(CoreStage::Update, DEBUG, SystemStage::single_threaded())

            // systems are added to the `CoreStage::Update` stage by default
            .add_system(player_gather_xp)
            .add_system(player_take_damage)

            // add our debug systems
            .add_system_to_stage(DEBUG, debug_player_hp)
            .add_system_to_stage(DEBUG, debug_stats_change)
            .add_system_to_stage(DEBUG, debug_new_hostiles)

            .run();
    }

如果你需要管理你的系统之间相对何时运行,通常最好避免使用阶段,而使用明确的系统排序。阶段限制了并行执行和你游戏的性能。

然而,当你真的想确保所有先前的系统执行结束,阶段可以使事情更容易组织。阶段也是应用命令的唯一方法。

如果你有一些系统的执行需要依赖于其他系统通过使用命令操作的结果,并且需要在同一帧内完成,那么将这些系统放入单独的阶段是实现这一目标的唯一途径。