0Pricing
Learn Rust Coding · レッスン

ECSの考え方

エンティティ、コンポーネント、システムについて学びます。

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

ECSで解決できること

BevyはEntity Component System(ECS)パターンを基盤に構築されています。深い継承階層の代わりに、小さく独立したデータの要素を組み合わせて振る舞いを構成します。

このデータ指向設計により、メモリ配置がキャッシュフレンドリーになり、エンジンはほとんど追加コストなしでCPUコア間に処理を並列化できます。

エンティティは単なるID

エンティティは軽量な識別子、つまり世代付きインデックスにすぎません。データを所有せず、それ自体には振る舞いもありません。

データベースの行を指すキーのようなものだと考えてください。そのキーにアタッチされたコンポーネントが、「Player」や「Bullet」のようにエンティティに意味を与えます。

// An Entity is a tiny handle
struct Entity {
    index: u32,
    generation: u32,
}

コンポーネントは純粋なデータ

コンポーネントはComponentをderiveする単純なRust構造体です。状態を保持しますが、ロジックは含みません。

コンポーネントは小さく、役割を絞ってください。位置、速度、体力は、1つの巨大な構造体ではなく、3つの別々のコンポーネントにします。

use bevy::prelude::*;

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

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

システムにロジックを記述する

システムはコンポーネントを操作する通常の関数です。ゲームロジックはすべてここに記述します。

Bevyは各システムのパラメーターを調べて、どのデータにアクセスするかを判断します。その後、競合しないシステムを並列実行するようスケジュールします。

fn move_system(mut query: Query<(&mut Position, &Velocity)>) {
    for (mut pos, vel) in &mut query {
        pos.x += vel.x;
        pos.y += vel.y;
    }
}

Queryでデータを取得する

Queryは、特定のコンポーネント一式を持つエンティティを宣言的に要求します。Bevyは条件に一致するエンティティだけを返します。

&Tで共有アクセスを、&mut Tで排他的アクセスを要求できます。この借用情報が並列スケジューラーの動作を決めます。

// Entities with BOTH Position and Velocity
fn report(query: Query<(&Position, &Velocity)>) {
    for (pos, vel) in &query {
        info!("at {},{} moving {},{}", pos.x, pos.y, vel.x, vel.y);
    }
}

Queryをフィルタリングする

Queryの2番目の型パラメーターはフィルターです。WithとWithoutを使うと、そのコンポーネントのデータを借用せずに結果を絞り込めます。

これはタグコンポーネントに最適です。タグコンポーネントとは、エンティティの役割を示す空の構造体です。

#[derive(Component)]
struct Player;

fn player_only(query: Query<&Position, With<Player>>) {
    for pos in &query {
        info!("player at {},{}", pos.x, pos.y);
    }
}

リソース:グローバルな状態

ゲーム全体で1つだけ必要なデータもあります。スコア、経過時間、ゲーム設定などです。これらはコンポーネントではなく、リソースとして扱います。

システムでは、読み取りにはRes<T>を、書き込みにはResMut<T>を使ってアクセスします。

#[derive(Resource)]
struct Score(u32);

fn show_score(score: Res<Score>) {
    info!("Score: {}", score.0);
}

Appビルダー

すべての要素はAppで接続します。プラグインやリソースを追加し、スケジュールに対してシステムを登録します。

DefaultPluginsはウィンドウ管理、レンダリング、入力、時間を提供するため、ゲームプレイに集中できます。

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .insert_resource(Score(0))
        .add_systems(Update, show_score)
        .run();
}

スケジュール:StartupとUpdate

システムはスケジュール内で実行されます。Startupはアプリの起動時に1回だけ実行され、ワールドの生成に最適です。

Updateは毎フレーム実行され、移動、入力、ロジックを記述する場所です。Bevyには、決定論的な物理ステップ用のFixedUpdateもあります。

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

コンポジションが優れている理由

空を飛び、毒状態にもなる敵が必要ですか?FlyingとPoisonedコンポーネントをアタッチするだけです。新しいクラスも継承階層も必要ありません。

どのシステムがどのコンポーネントの組み合わせに一致するかによって、振る舞いが生まれます。そのため、機能を追加しやすく、リファクタリングのコストも小さくなります。

// Same systems, new combinations
commands.spawn((Position{x:0.0,y:0.0}, Velocity{x:1.0,y:0.0}, Flying, Poisoned));

自然に得られる並列性

各システムがデータへのアクセス方法を宣言するため、Bevyのスケジューラーは競合するシステムを把握できます。競合しないシステムは自動的に別々のスレッドで実行されます。

単一スレッド向けに見えるコードを書くだけで、エンジンが借用の宣言から並列性を引き出します。ロックも手動のスレッド処理も必要ありません。

確認問題

ECSにおける各要素の役割を理解できているか確認しましょう。

まとめ:ECSの考え方

エンティティはID、コンポーネントはデータ、システムはロジック、リソースはグローバルな状態です。Appがスケジュールを通じてこれらを結び付けます。

小さなコンポーネントを組み合わせ、システムにそれらを照合させることで、柔軟で並列化しやすく、キャッシュフレンドリーなゲームを作れます。次はエンティティを生成して動かします。

よくある質問

「ECSの考え方」レッスンは無料ですか?

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

「ECSの考え方」で何を学びますか?

エンティティ、コンポーネント、システムについて学びます。 ブラウザで直接実行するハンズオンコードでLearn Rust Codingを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

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

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

「ECSの考え方」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

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