关于 bevy-ecs-queries
面向 Bevy 0.19 ECS 查询开发的技能,适用于在系统中读取或修改组件、筛选实体及并行迭代。重点说明新版查询边界、迭代方式和常见错误处理。
主要功能
- 01读取和修改实体组件
- 02按组件与变更状态筛选
- 03使用 par_iter_mut 并行迭代
- 04通过查询 lens 借用数据子集
- 05说明 0.19 查询边界变化
适用场景
- 01编写 Bevy 系统中的查询逻辑
- 02筛选或并行处理大量实体
- 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