mcpField
B
bevy-ecs-queries

bevy-ecs-queries

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

关于 bevy-ecs-queries

面向 Bevy 0.19 ECS 查询开发的技能,适用于在系统中读取或修改组件、筛选实体及并行迭代。重点说明新版查询边界、迭代方式和常见错误处理。

主要功能

  1. 01读取和修改实体组件
  2. 02按组件与变更状态筛选
  3. 03使用 par_iter_mut 并行迭代
  4. 04通过查询 lens 借用数据子集
  5. 05说明 0.19 查询边界变化

适用场景

  1. 01编写 Bevy 系统中的查询逻辑
  2. 02筛选或并行处理大量实体
  3. 03排查升级后的查询编译错误

安装

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

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

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

详细介绍

Bevy 0.19 — ECS 查询

何时使用此技能

  • 在系统中读取或写入组件。
  • 按存在性(With/Without)、交替条件(Or)或变更检测(Changed/Added)进行过滤。
  • 使用 par_iter_mut 并行处理大量实体。
  • 通过透镜(transmute_lens)借用查询的子集。
  • 升级到 0.19 后遇到提及 IterQueryData 或 SingleEntityQueryData 的编译器错误。

规范模式

use bevy::prelude::*;

#[derive(Component, Default)]
struct Health(f32);

#[derive(Component, Default)]
struct Velocity(Vec3);

#[derive(Component)]
struct Player;

#[derive(Component)]
struct Enemy;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Update, (
            move_things,
            on_health_changed,
            damage_visible_enemies,
            integrate_in_parallel,
        ))
        .run();
}

// Sequential iteration. `&` for read, `&mut` for write.
fn move_things(time: Res<Time>, mut q: Query<(&Velocity, &mut Transform)>) {
    let dt = time.delta_secs();
    for (vel, mut tf) in &mut q {
        tf.translation += vel.0 * dt;
    }
}

// Change detection. `Changed<T>` triggers on insert OR mutation.
// `Added<T>` triggers only on insert.
fn on_health_changed(q: Query<(Entity, &Health), Changed<Health>>) {
    for (entity, hp) in &q {
        info!("entity {:?} now has {} hp", entity, hp.0);
    }
}

// Combined filters. `With`/`Without` constrain entities;
// `Or<(...)>` alternates over filters (not components).
fn damage_visible_enemies(
    mut q: Query<&mut Health, (With<Enemy>, Without<Player>, Or<(Added<Enemy>, Changed<Transform>)>)>,
) {
    for mut hp in &mut q {
        hp.0 -= 1.0;
    }
}

// Parallel iteration. Use when N is large (>10k) and per-entity work is non-trivial.
// Cannot use `Commands` or external mutable state — task pool runs items in parallel.
fn integrate_in_parallel(mut q: Query<(&Velocity, &mut Transform)>) {
    q.par_iter_mut().for_each(|(vel, mut tf)| {
        tf.translation += vel.0 * 0.016;
    });
}

// Query lens: temporarily view a query as a narrower one. Useful for
// passing a stricter query into a helper without re-binding the system's
// SystemParam list.
#[allow(dead_code)]
fn use_lens(mut q: Query<(&mut Transform, &Velocity)>) {
    // Read-only narrowed view of just the Transform column.
    let mut lens = q.transmute_lens::<&Transform>();
    let _read_only: Query<&Transform> = lens.query();
}

Bevy 0.19 注意事项

  • 0.19 为嵌套查询访问增加了约束。 泛型可变迭代通常需要 D: IterQueryData;单实体访问、查询转型/连接、遍历和排序可能需要 D: SingleEntityQueryData。只读迭代仍保留更宽泛的约束。
  • 不可迭代的查询数据使用借用式迭代。 保持 D: QueryData,调用 let mut iter = query.iter_mut(),然后在嵌套查询项可能访问多个实体时,反复调用 iter.fetch_next()。
  • EntityMut::get_components_mut::<(&mut A, &mut B)>() 是从同一实体中安全获取两个 &mut 的方式,现在带有 SingleEntityQueryData 约束。它返回 Result;不要使用未经检查的别名访问。
  • Query::get/get_mut 返回 Result,而非 Option。 错误类型携带实体信息,因此如果你确实需要知道查找失败的原因,就不要用 .ok() 将其忽略。
  • Or<(With<A>, With<B>)> — Or 在过滤器之间交替,而不是在原始组件类型之间。Or<(A, B)> 无法编译。
  • Changed/Added 基于 tick 检测。 它们会与系统上次运行时的状态比较,因此普通运行条件不会丢失期间发生的变更。它们报告的是修改,而非语义上的不等;如果需要捕获每次发生的情况或旧值/新值,请使用观察者/消息。
  • 不要将 par_iter_mut 与 Commands 搭配使用。 从顺序系统中执行生成/销毁操作,并让该系统消费由并行系统写入的 Resource 队列。

另请参阅

  • bevy-ecs-components — 声明此处查询的组件。
  • bevy-ecs-systems — 在 SystemParam 和运行条件中使用查询。
  • bevy-migration-0-17-to-0-18 — EntityMut::get_components_mut 和 tick 类型迁移。
  • bevy-migration-0-18-to-0-19 — 嵌套查询 trait 约束和查询中的资源。

评论

支持 Markdown