mcpField
B
bevy-ecs-systems

bevy-ecs-systems

github.com/chrisgliddon开发2690 次安装9 周前更新
代码仓库

关于 bevy-ecs-systems

bevy-ecs-systems 是面向 Bevy 0.19 ECS 系统、参数、集合、运行条件和状态调度的技能,适用于 Bevy 应用开发者。它重点说明系统排序、运行时移除及调度歧义错误的处理。

主要功能

  1. 01用 SystemParam 封装状态
  2. 02用 SystemSet 分组和排序系统
  3. 03通过运行条件控制系统执行
  4. 04响应状态转换触发系统
  5. 05运行时从集合移除系统
  6. 06诊断调度歧义错误

适用场景

  1. 01将相关系统组织到集合中
  2. 02仅在条件满足时运行系统
  3. 03处理应用状态转换
  4. 04运行时移除调试系统

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/chrisgliddon/bevy-skills --skill bevy-ecs-systems

安装后在 Claude Code 中输入/bevy-ecs-systems确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
ordering.md
run-conditions.md
runtime-removal.md
state-schedules.md
system-params.md
system-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_neqreferences/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