0Pricing
Learn Rust Coding · レッスン

エンティティを生成して動かす

画面上にオブジェクトを配置します。

「エンティティを生成して動かす」はCoddyKit上の無料Learn Rust Codingレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはLearn Rust Coding学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Learn Rust Codingコースには全4レッスンが含まれています。

Commands:遅延生成

システムが並列実行されている間、Worldを直接変更することはできません。代わりに、Commandsを通じて構造変更をキューに追加します。

生成、削除、コンポーネントの追加は記録され、スケジュールステージの最後に適用されます。これにより、安全にアクセスできます。

fn setup(mut commands: Commands) {
    commands.spawn_empty();
}

Bundleで生成する

Bundleは、まとめて挿入するコンポーネントのグループです。最も単純なBundleは、コンポーネントのタプルです。

Bevyはタプルの各要素をアタッチするコンポーネントとして扱うため、1回のspawn呼び出しでエンティティに初期データをすべて与えられます。

fn setup(mut commands: Commands) {
    commands.spawn((
        Position { x: 0.0, y: 0.0 },
        Velocity { x: 1.5, y: 0.0 },
        Player,
    ));
}

見るためのカメラ

カメラがなければ何も描画されません。2Dゲームでは、StartupシステムでCamera2dを生成します。

カメラ自体もカメラ用コンポーネントを持つエンティティです。これはECSの一貫性を示すもう1つの例です。シーン内のすべての要素がエンティティです。

fn setup(mut commands: Commands) {
    commands.spawn(Camera2d::default());
}

スプライトを生成する

何かを描画するには、エンティティにSpriteとTransformを与えます。Transformはワールド空間での位置、回転、スケールを保持します。

色付きのスプライトには画像アセットが必要ないため、アート素材を読み込む前の移動処理のプロトタイピングに便利です。

commands.spawn((
    Sprite::from_color(Color::srgb(0.2, 0.7, 1.0), Vec2::new(40.0, 40.0)),
    Transform::from_xyz(0.0, 0.0, 0.0),
    Velocity { x: 80.0, y: 0.0 },
));

Transformと独自のPositionの違い

実際のBevyゲームでは、独自のPositionよりも組み込みのTransformを動かすのが一般的です。レンダリングがTransformを直接読み取るためです。

平行移動はVec3です。2Dではxとyを変更し、描画順にはzを使います。

#[derive(Component)]
struct Velocity { x: f32, y: f32 }

fn apply_velocity(mut q: Query<(&mut Transform, &Velocity)>) {
    for (mut tf, vel) in &mut q {
        tf.translation.x += vel.x;
        tf.translation.y += vel.y;
    }
}

Queryを可変で反復処理する

コンポーネントのデータを変更するには、&mut Tを要求し、&mut queryを反復処理します。各要素から可変参照が得られます。

Bevyは、競合する可変アクセスを2つのシステムが同時に保持しないことを保証します。そのため、ほかのシステムが実行中でもこのループは安全です。

fn move_all(mut q: Query<&mut Transform, With<Player>>) {
    for mut tf in &mut q {
        tf.translation.x += 1.0;
    }
}

多数のエンティティを生成する

ループを使うとレベルを構成できます。Rustのforループ内でspawnを呼び出し、障害物のグリッドや敵の群れを作成します。

各反復で独自のコマンドがキューに追加され、ステージの境界ですべてまとめて適用されます。

fn spawn_row(mut commands: Commands) {
    for i in 0..5 {
        commands.spawn((
            Sprite::from_color(Color::WHITE, Vec2::splat(20.0)),
            Transform::from_xyz(i as f32 * 30.0, 0.0, 0.0),
        ));
    }
}

エンティティを削除する

commands.entity(id).despawn()でエンティティを完全に削除できます。コンポーネントが解放され、エンティティのインデックスが再利用されます。

通常は、エンティティのEntityIDを取得したシステムから削除します。たとえば、画面外に出た弾丸などです。

fn cleanup(mut commands: Commands, q: Query<(Entity, &Transform)>) {
    for (e, tf) in &q {
        if tf.translation.y > 600.0 {
            commands.entity(e).despawn();
        }
    }
}

後からコンポーネントを追加する

実行時にinsertを使って、既存のエンティティに新しいコンポーネントをアタッチできます。これにより、パワーアップしたプレイヤーにShieldタグを与えられます。

削除もremove::<T>()を使って同じように行います。どちらも構造変更なので、Commandsを通じて実行されます。

commands.entity(player).insert(Shield { hits: 3 });
// later
commands.entity(player).remove::<Shield>();

レイヤー分けに使うZ

2Dでは、Transformの平行移動に含まれるz値が描画順を決めます。zが大きいほど手前に描画されます。

背景のzを低くし、プレイヤーのzを高くして、スプライトが背景の後ろに隠れないようにします。

// background behind, player in front
commands.spawn((bg_sprite, Transform::from_xyz(0.0, 0.0, 0.0)));
commands.spawn((player_sprite, Transform::from_xyz(0.0, 0.0, 10.0)));

処理を接続する

Startupで生成し、Updateで動かします。Startupシステムはカメラとエンティティを1回だけ作成し、Updateシステムは毎フレームそれらを更新します。

この分離により、初期化処理が毎フレームのホットパスに入り込むのを防げます。

App::new()
    .add_plugins(DefaultPlugins)
    .add_systems(Startup, setup)
    .add_systems(Update, apply_velocity)
    .run();

確認問題

構造変更がどのように適用されるか考えてみましょう。

まとめ:生成と移動

Commandsを使ってBundleでエンティティを生成し、SpriteとTransformで描画し、Updateシステム内でTransformを変更して動かします。

エンティティの削除とコンポーネントの挿入もCommandsで行います。次は、キーボード入力と実際の経過時間に応じて移動させます。

よくある質問

「エンティティを生成して動かす」レッスンは無料ですか?

はい。「エンティティを生成して動かす」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Learn Rust Codingコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Learn Rust Codingコースには全4レッスンが含まれています。

「エンティティを生成して動かす」で何を学びますか?

画面上にオブジェクトを配置します。 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Learn Rust Codingを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのLearn Rust Codingは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「エンティティを生成して動かす」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このLearn Rust Codingレッスンでコードを書いて実行できますか?

はい。すべてのLearn Rust Codingレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ECSの考え方
  2. エンティティを生成して動かす
  3. 入力と時間を扱う
  4. 衝突とゲーム状態
← Learn Rust Codingに戻る