佐藤のメモ帳

Rust, Python, Java, AWS, etc...

Rust Bevy EntityとComponentについて

はじめに

本記事はBevy非公式(と思えないほど素晴らしい)サイトのメモである。

bevy-cheatbook.github.io

メモ

BevyにおいてEntityとはComponentを特定するためのIDである。
また、ComponentとはEntityに紐づくデータである。

Componentはstructまたはenumの型で定義する。

struct Health {
    hp: f32,
    extra: f32,
}

型は一意でなければならない。Entity毎型毎に1つのみインスタンスが存在できる。
これでは不便なので、New Typeパターンで単純型をComponent化する。

struct PlayerXp(u32);

struct PlayerName(String);

以下の空ComponentはマーカーComponentと呼ぶ。
Queryフィルタリングを使う際役に立つ。

/// メニューUIに関するEntityに以下を付与することで、これらを識別する時役に立つ
struct MainMenuUI;
/// プレイヤーを識別する時役に立つ
struct Player;
/// エネミーを識別する時役に立つ
struct Enemy;

SystemはQueryを使用してComponentにアクセスする。

Component Bundleとはテンプレートのようなものである。
共通のComponentを持つEntityを複数作成する際に役に立つ。

#[derive(Bundle)]
struct PlayerBundle {
    xp: PlayerXp,
    name: PlayerName,
    health: Health,
    _p: Player,

    // BundleにBundleを追加することもできる
    #[bundle]
    sprite: SpriteSheetBundle,
}

BevyではComponentのタプルをBundleと見なす。

// バンドル!
(ComponentA, ComponentB, ComponentC)

注意!

ComponentもBundleもstructであるため、BevyやRustコンパイラはどれがどちらかを判断することができない。
もし、ComponentであるべきところをBundleを使用したとしてもコンパイルエラーは発生せず、Bundleとして扱われる。
#[bundle]アトリビュートを付与して、どちらかを明確にすること。
Queryの対象はComponentであるため、明確にしないと思わぬバグになる。