Rust Bevy Queryについて
はじめに
本記事はBevy非公式(と思えないほど素晴らしい)サイトのメモである。
メモ
BevyにおいてQueryとはEntityのComponentを指定した条件で取得し、アクセスする機能
である。
fn check_zero_health( // `Health`と`Transform`Componentを持つEntityにアクセスする // `Health`は読み取り専用で取得し、`Transform`は変更可能(mut)で取得する // オプション: `Player`Componetが存在するなら取得する mut query: Query<(&Health, &mut Transform, Option<&Player>)>, ) { // 一致する全てのEntityを取得する for (health, mut transform, player) in query.iter_mut() { eprintln!("Entity at {} has {} HP.", transform.translation, health.hp); // HPが0なら、中央に移動 if health.hp <= 0.0 { transform.translation = Vec3::ZERO; } if let Some(player) = player { // ここではEntityは`Player` } } }
Entityから特定のComponentを取得する例
if let Ok((health, mut transform)) = query.get_mut(entity) { // Componentに対する何らかの操作 } else { // Entityは指定したComponentを持っていない }
EntityのIDを取得する例
// `Query`に`Entity`を追加し、EntitiyのIDを取得する fn query_entities(q: Query<(Entity, /* ... */)>) { for (e, /* ... */) in q.iter() { // `e` はEntityのID } }
QueryでEntityを1つに特定できる場合は、single/single_mutで取得することができる。 上の例のようにループする必要はない。
fn query_player(mut q: Query<(&Player, &mut Transform)>) { let (player, mut transform) = q.single_mut() .expect("There should always be exactly one player in the game!"); }
注意
QueryはComponentに対して機能する。Bundleを使用して Entityを作成している場合、そのBundleから特定のComponentをQueryで参照する必要がある。
Query Filters
Query Filterを使用して、QueryするEntityを絞り込むことができる。 特定のComponentを持つEntityを取得する場合はWith/Withoutを使用する。
fn debug_player_hp( // Enemyを除くPlayerの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); } } }