Latest commit 209b722
查询
相关的官方文档:[ecs_guide]
Query 能访问实体的组件。
#![allow(unused)] fn main() { fn check_zero_health( // 访问带有 `Health` 和 `Transform` 组件的实体 // 获取对 `Health` 的只读访问和对 `Transform` 的可变访问 // 可选组件:如果 `Player` 存在,获取只读访问 mut query: Query<(&Health, &mut Transform, Option<&Player>)>, ) { // 获取所有匹配的实体 for (health, mut transform, player) in query.iter_mut() { eprintln!("Entity at {} has {} HP.", transform.translation, health.hp); // 读取 `Health`,修改 `Transform` if health.hp <= 0.0 { transform.translate = Vec3::ZERO; } // 判断 `Player` 是否存在 if let Some(player) = player { // 做一些事 } } } }
获取与特定实体关联的组件:
#![allow(unused)] fn main() { if let Ok((health, mut transform)) = query.get_mut(entity) { // 做一些事 } else { // 实体中没有 query 要求的组件 } }
获取Query访问的实体的 ID:
#![allow(unused)] fn main() { // 把 `Entity` 添加到 `Query` 来获取 Entity 的 ID fn query_entites(q: Query<(Entity, /* ... */)>) { for (e, /* ... */) in q.iter() { // `e` 就是我们正在访问的 Entity 的 ID } } }
如果明确地知道 Query 只匹配一个实体,可以用 single 或 single_mut(返回 Result),而不是 iter 或 iter_mut:
#![allow(unused)] fn main() { fn query_player(mut q: Query<(&Player, &mut Transform)>) { let (player, mut transform) = q.single_mut().expect("单机游戏只有一个玩家!"); // 做一些事 } }
(如果 single 查询到多个实体,会 panic!)
包
Query 查询的是实体的组件,如果某个实体从 Bundle 创建,那么在 Query 中不要查询 Bundle,要查询 Bundle 中的组件。记住:查询“组件”。
查询过滤器
过滤器的作用是缩小查询范围。用 With 或 Without 来获取带有特定组件的实体。
#![allow(unused)] fn main() { fn debug_player_hp( // 访问 `Health`,但只针对队友。可选:具有名字 query: Query<(&Health, Option<&PlayerName>), (With<Player>, Without<Enemy>)>, ) { // 获取所有匹配的实体 for (health, name) in query.iter() { if let Some(name) = name { eprintln!("Player {} has {} HP.", name.0, health.hp); } else { eprintln!("Unknown player has {} HP.", health.hp); } } } }
可以组合多个过滤器:
- 元组中包含多个过滤器:所有过滤器起作用(逻辑与)。
Or<...>中包含多个过滤器:过滤器其中之一起作用(逻辑或)。- (注意元组内部)