关于 bevy-ecs-systems
bevy-ecs-systems 是面向 Bevy 0.19 ECS 系统、参数、集合、运行条件和状态调度的技能,适用于 Bevy 应用开发者。它重点说明系统排序、运行时移除及调度歧义错误的处理。
主要功能
- 01用 SystemParam 封装状态
- 02用 SystemSet 分组和排序系统
- 03通过运行条件控制系统执行
- 04响应状态转换触发系统
- 05运行时从集合移除系统
- 06诊断调度歧义错误
适用场景
- 01将相关系统组织到集合中
- 02仅在条件满足时运行系统
- 03处理应用状态转换
- 04运行时移除调试系统
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ chrisgliddon/ bevy-skills --skill bevy-ecs-systems安装后在 Claude Code 中输入/bevy-ecs-systems确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/ordering.mdrun-conditions.mdruntime-removal.mdstate-schedules.mdsystem-params.mdsystem-sets.md详细介绍
Bevy 0.19 — ECS 系统(参数、集合、运行条件)
何时使用此技能
- 通过
#[derive(SystemParam)]将相关状态打包到单个系统参数中。 - 将系统分组到
SystemSet中,以便调用方针对整个组设置执行顺序。 - 使用运行条件(
run_if、on_message、in_state、resource_exists、any_with_component)控制系统是否运行。 - 通过
OnEnter(S)/OnExit(S)/OnTransition { from, to }接入状态转换。 - 在运行时热移除系统(例如,拆除调试覆盖层),使用
remove_systems_in_set。 - 遇到
ScheduleBuildError歧义 panic——执行器不再自行猜测。
规范模式
use bevy::ecs::system::SystemParam;
use bevy::prelude::*;
#[derive(SystemSet, Hash, PartialEq, Eq, Clone, Debug)]
enum GameLoop { Input, Simulate, Render }
#[derive(States, Default, Hash, PartialEq, Eq, Clone, Debug)]
enum AppState { #[default] Loading, Playing }
#[derive(Resource, Default)]
struct Score(u32);
#[derive(Message)]
struct GoalScored { team: u8 }
// Composite param: pass one argument, get four.
// 'w = world borrow; 's = system-local state borrow.
#[derive(SystemParam)]
struct GameCtx<'w, 's> {
time: Res<'w, Time>,
score: ResMut<'w, Score>,
goals: MessageReader<'w, 's, GoalScored>,
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.init_resource::<Score>()
.add_message::<GoalScored>()
.init_state::<AppState>()
.configure_sets(Update, (GameLoop::Input, GameLoop::Simulate, GameLoop::Render).chain())
// State schedule: fires once when entering Playing.
.add_systems(OnEnter(AppState::Playing), spawn_level)
// State schedule: fires once when leaving Playing.
.add_systems(OnExit(AppState::Playing), despawn_level)
.add_systems(Update, read_input.in_set(GameLoop::Input))
.add_systems(
Update,
tally_goals
.in_set(GameLoop::Simulate)
.run_if(on_message::<GoalScored>),
)
.add_systems(Update, draw_hud.in_set(GameLoop::Render))
.run();
}
#[derive(Component)]
struct LevelEntity;
fn spawn_level(mut commands: Commands) {
commands.spawn((LevelEntity, Name::new("level")));
}
fn despawn_level(mut commands: Commands, query: Query<Entity, With<LevelEntity>>) {
for e in &query { commands.entity(e).despawn(); }
}
fn read_input(mut writer: MessageWriter<GoalScored>) {
writer.write(GoalScored { team: 0 });
}
fn tally_goals(mut ctx: GameCtx) {
let _ = ctx.time.delta_secs();
for goal in ctx.goals.read() {
ctx.score.0 += 1;
info!("team {} scored, total {}", goal.team, ctx.score.0);
}
}
fn draw_hud(score: Res<Score>) { let _ = score.0; }
运行条件速查表
| 内置条件 | 触发时机 |
|---|---|
on_message::<M> | Messages<M> 缓冲区中有未读取的条目。 |
resource_exists::<R> | World 中存在资源 R。 |
resource_changed::<R> | R 在此 tick 中被修改。 |
in_state(MyState::X) | 当前的 State<MyState> 等于 X。 |
state_changed::<MyState> | 状态在此 tick 中发生了变化。 |
any_with_component::<C> | 至少有一个实体拥有 C。 |
使用 .and() / .or() 组合:run_if(in_state(GameState::Playing).and(resource_exists::<NetSession>()))。
主题
| 主题 | 参考资料 |
|---|---|
#[derive(SystemParam)]、'w/'s 生命周期、Local<T>、Commands 延迟应用 | references/system-params.md |
#[derive(SystemSet)] 要求、.in_set、.configure_sets、.chain() | references/system-sets.md |
所有内置条件、.and()/.or()/not()、自定义条件、开销规则 | references/run-conditions.md |
OnEnter(S) / OnExit(S) / OnTransition、NextState<S>、set_if_neq | references/state-schedules.md |
.before、.after、.chain()、.ambiguous_with、调试歧义错误 | references/ordering.md |
remove_systems_in_set、清理策略、跨 schedule 运行时移除、边界副作用 | references/runtime-removal.md |
Bevy 0.19 注意事项
- 共享访问不会定义执行顺序。 存在冲突的可变系统会串行执行,
但彼此的相对顺序未指定。启用歧义诊断,并在行为依赖顺序时添加
.before、.after或.chain()。参见 references/ordering.md。 - 使用
MessageReader/MessageWriter,而不是EventReader/EventWriter。 它们在 0.17 中更名。Trait 派生为#[derive(Message)];注册方式为app.add_message::<M>()。 - 在 0.18 中,
next_state.set(S)总会触发OnExit/OnEnter。 使用set_if_neq以恢复旧行为。参见 references/state-schedules.md。 - 不要通过
Schedules移除当前正在运行的 schedule。 它会暂时从该资源中消失。应从之后运行的其他 schedule(例如Last)中移除Update系统。参见 references/runtime-removal.md。 - 在 0.19 中,
Resource: Component。 泛型系统参数仍使用Res<T>/ResMut<T>,但T: Resource约束不再能证明T不会出现在组件查询中。
另请参阅
bevy-core-concepts— 应将系统添加到哪个 schedule(Startup、Update、FixedUpdate)。bevy-ecs-queries— 查询是众多SystemParam之一;Changed<T>/Added<T>过滤器。bevy-ecs-components— 定义系统操作的Component类型。bevy-migration-0-17-to-0-18— 完整的 Message/Event 更名、MaterialPlugin变更。bevy-migration-0-18-to-0-19— 资源约束和执行器配置。
评论
支持 Markdown