mcpField
B
bevy-ecs-expert

bevy-ecs-expert

github.com/sickn33開発48.7k169 回インストール今日更新
リポジトリ

bevy-ecs-expert について

Rustでゲームを開発する人向けのBevy ECSガイドです。データ指向のゲームロジック、システムのスケジューリング、クエリ、リソース管理を扱い、クエリの絞り込みや並列実行の考え方も示します。

主な機能

  1. 01データのみのコンポーネント定義
  2. 02クエリを使ったシステム作成
  3. 03グローバルリソース管理
  4. 04システムのスケジュールと順序設定
  5. 05エンティティクエリの絞り込み
  6. 06クエリ競合の解決

活用シーン

  1. 01Bevy ECSでゲームロジックを構成
  2. 02互換性のあるシステムの並列実行
  3. 03エンティティ反復の最適化
  4. 04オブジェクト指向ロジックの再構成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sickn33/agentic-awesome-skills --skill bevy-ecs-expert

インストール後、Claude Code で/bevy-ecs-expertを入力して読み込まれたか確認します。

詳細

Bevy ECS エキスパート

概要

Bevy のデータ指向 ECS アーキテクチャを使用して、高パフォーマンスなゲームロジックを構築するためのガイドです。システムの構成方法、クエリの最適化、リソースの管理、並列実行の活用方法を学びます。

このスキルを使用する場面

  • Rust で Bevy エンジンを使用したゲームを開発するとき。
  • 並列実行が必要なゲームシステムを設計するとき。
  • キャッシュミスを最小限に抑えてゲームのパフォーマンスを最適化するとき。
  • オブジェクト指向ロジックをデータ指向の ECS パターンにリファクタリングするとき。

手順ガイド

1. コンポーネントの定義

データにはシンプルな構造体を使用します。bevy::prelude::* をインポートし、リフレクションやインスペクションが必要な場合にのみ Reflect を追加します。以下のスニペットはそれぞれ別の方法を示しているため、同じスコープ内で Player と Velocity の定義を重複させないでください。

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

#[derive(Component)]
struct Player;
2. システムの記述

システムは、コンポーネントをクエリする通常の Rust 関数です。

fn movement_system(
    time: Res<Time>,
    mut query: Query<(&mut Transform, &Velocity), With<Player>>,
) {
    for (mut transform, velocity) in &mut query {
        transform.translation.x += velocity.x * time.delta_secs();
        transform.translation.y += velocity.y * time.delta_secs();
    }
}
3. リソースの管理

グローバルデータ(スコア、ゲーム状態)には Resource を使用します。

#[derive(Resource, Default)]
struct GameState {
    score: u32,
}

fn score_system(mut game_state: ResMut<GameState>) {
    game_state.score += 10;
}

この例の score_system は各 Update でスコアを増やします。フレームレートに依存しないスコア動作を暗示するのではなく、意味のあるスコア加算にはゲームプレイイベントか明示的なタイマーを使用してください。

4. システムのスケジューリング

必要に応じて実行順序を定義しながら、App ビルダーにシステムを追加します。

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .init_resource::<GameState>()
        .add_systems(Update, (movement_system, score_system).chain())
        .run();
}

例

例 1:必須コンポーネントを使用したエンティティの生成
use bevy::prelude::*;

#[derive(Component, Reflect, Default)]
#[require(Velocity, Sprite)]
struct Player;

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

fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
    commands.spawn((
        Player,
        Velocity { x: 10.0, y: 0.0 },
        Sprite::from_image(asset_server.load("player.png")), 
    ));
}
例 2:クエリフィルター

With と Without を使用して、エンティティを効率的にフィルタリングします。

fn enemy_behavior(
    query: Query<&Transform, (With<Enemy>, Without<Dead>)>,
) {
    for transform in &query {
        // Only active enemies processed here
    }
}

ベストプラクティス

  • ✅ 推奨: Query フィルター(With、Without、Changed)を使用して、反復処理の回数を減らします。
  • ✅ 推奨: 読み取り専用アクセスで十分な場合は ResMut より Res を優先し、並列実行を可能にします。
  • ✅ 推奨: 複雑なエンティティをまとめて生成するには Bundle を使用します。
  • ❌ 非推奨: 重いロジックをコンポーネント内に格納しないでください。コンポーネントは純粋なデータとして維持します。
  • ❌ 非推奨: コンポーネント内で RefCell や内部可変性を使用しないでください。通常の ECS の借用を優先します。内部可変性を使う設計でも、有効な Send/Sync と明確な同期上の理由が必要です。

トラブルシューティング

問題: 「Conflict」エラーでシステムがパニックします。
解決策: スケジューラーは通常、競合するシステムの実行順序を調整します。Bevy B0001 は多くの場合、単一のシステム内にある互換性のないクエリが原因です。適切に互いに素となる With/Without フィルター、または ParamSet を使用してください。2 つのシステムをチェーンしても、単一システム内のパラメーター間の競合は解消されません。Bevy B0001 を参照してください。

制限事項

  • プロジェクトで使用する Bevy のバージョンを固定し、移行/API ガイドを確認してください。現在の例では delta_secs と必須コンポーネントを使用していますが、古い Bevy のバージョンでは異なる場合があります。Enemy/Dead はアプリケーション側で定義するコンポーネントマーカーであり、player.png はアプリケーションのアセットで、同梱ファイルではありません。ここではエンジンのコンパイルやパフォーマンスのベンチマークを主張していません。
  • 出力を、環境固有の検証、テスト、または専門家によるレビューの代わりとして扱わないでください。
  • 必要な入力、権限、安全上の境界、または成功基準が不足している場合は、作業を中断して確認を求めてください。

コメント