Latest commit d7a897d

阶段

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

各阶段之间的边界实际上是硬同步点。同步点可以确保上一阶段的所有系统全部完成后,下一阶段的系统才能开始,并且在某一时刻没有任何系统运行。

这样才能应用 Commands(或者说能安全地应用 Commands)。系统用 Commands 的任何操作只会会在每个阶段结束时进行。

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

  • main app(CoreStage):FirstPreUpdateUpdatePostUpdateLast
  • sub-app(RenderStage):ExtractPrepareQuenePhaseSortRenderCleanup

把系统添加进 App 时,默认被添加到 CoreStage::Update

Bevy 的内部系统在其他阶段,与游戏逻辑分开,确保了自身的正确排序。

如果想把系统添加到 Bevy 的内部阶段,要提防与 Bevy 的内部系统发生潜在的意外交互。记住:Bevy 的内部系统是用普通系统和 ECS 实现的,就像你自己的写的系统一样!

可以添加自定义阶段。例如,与调试有关的系统应该在游戏逻辑后面执行:

fn main() {
	// 用 debug 标签来表示 “DEBUG 阶段”
	static DEBUG: &str = "debug";

	App::new()
		.add_plugins(DefaultPlugins)

		// 在 Bevy 的 Update 节点后面添加 “DEBUG 阶段”,并使 DEBUG 成为单线程
		.add_stage_after(CoreStage::Update, DEBUG, SystemStage::singel_threaded())

		// 这些系统默认添加到 `CoreStage::Update`
		.add_system(player_gather_xp)
		.add_system(player_take_damage)

		// 这些系统添加到 “DEBUG 阶段”
		.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();
}

如果要管理系统相对于彼此的先后运行顺序,最好不要用阶段,而要用显式系统排序。阶段限制了游戏的并行执行和性能。

但是,阶段能方便地确认所有系统是否已经全部完成,阶段也是应用 Commands 的唯一方式。

todo:未测试,不懂。 If you have systems that need to rely on the actions that other systems have performed by using Commands, and need to do so during the same frame, placing those systems into separate stages is the only way to accomplish that.