mcpField
G
godot-csharp

godot-csharp

github.com/gamedev-skills開発5.4k6.5k 回インストール1 日前に更新
リポジトリ

godot-csharp について

godot-csharpは、.NET 8とC#でGodot 4.7のゲームコードを書くためのスキルです。ノードスクリプト、ライフサイクル、エクスポート、シグナル、シーン生成、GDScript連携を解説します。

主な機能

  1. 01C#ノードスクリプトとライフサイクル
  2. 02[Export]によるインスペクター項目
  3. 03C#イベントとしてのシグナル
  4. 04PackedSceneによるシーン生成
  5. 05GDScriptノードの呼び出しとアクセス

活用シーン

  1. 01C#でGodotのゲームロジックを記述
  2. 02インスペクターで調整値を公開
  3. 03C#コードをシグナルに接続
  4. 04GDScriptスクリプトとの連携

インストール

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

$npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill godot-csharp

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

同梱ファイルreferences/csharp-setup-and-interop.md

詳細

Godot C# / .NET (4.x)

C# で Godot のゲームコードを作成します。ノードのサブクラス、エンジンのライフサイクル、エクスポート、イベントとしてのシグナル、GDScript との相互運用に対応しています。対象は Godot 4.7 (.NET / C#) と .NET 8 です。

使用する場面

  • Godot ゲームを C#(.cs + .csproj)でスクリプト化するとき、GDScript のイディオムを C# に変換するとき、[Export] フィールドを公開するとき、または [Signal] デリゲートと GetNode を接続するときに使用します。

使用しない場面: GDScript 固有の構文 → godot-gdscript、言語に依存しないエンジンの概念(シーン、物理演算、アニメーション) → 該当する godot-* スキルを使用してください。Godot .NET ビルドと .NET SDK のインストールが必要です。標準ビルドでは C# を実行できません。

基本的なワークフロー

  1. Godot .NET エディタービルドを使用し、対応する .NET 8 SDK をインストールします。 最初の C# スクリプトを作成すると、.csproj/.sln が生成されます。エディターまたは dotnet build でビルドします。
  2. すべてのノードスクリプトは、Godot の型を継承する partial クラスにします(ソースジェネレーターが partial に依存します)。ファイル名とクラス名はノードスクリプトに合わせます。
  3. ライフサイクルメソッドは PascalCase で、double 型の delta を使ってオーバーライドします。 _Ready()、_Process(double delta)、_PhysicsProcess(double delta) を使用します。
  4. 調整可能な値は [Export] で公開します。 GDScript の @export と同様に、インスペクターに表示されます。
  5. シグナルは XxxEventHandler という名前の [Signal] デリゲートとして宣言します。 EmitSignal(SignalName.Xxx, ...) で発火し、生成された C# の event を使って購読します。
  6. GetNode<T>("Path")(または %Unique)でノードを取得します。 必要に応じて Call/Get/Set で GDScript を呼び出します。

パターン

1. ノードスクリプト:ライフサイクル、[Export]、GetNode
using Godot;

public partial class Player : CharacterBody2D
{
    [Export] public float Speed = 200.0f;          // editable in the Inspector
    [Export] public float JumpVelocity = -400.0f;

    private const float Gravity = 1200.0f;
    private AnimatedSprite2D _sprite;

    public override void _Ready()
    {
        _sprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
    }

    public override void _PhysicsProcess(double delta)
    {
        Vector2 v = Velocity;                       // Velocity is a property here
        if (!IsOnFloor())
            v.Y += Gravity * (float)delta;          // delta is double; cast for float math
        if (Input.IsActionJustPressed("jump") && IsOnFloor())
            v.Y = JumpVelocity;

        float dir = Input.GetAxis("move_left", "move_right");
        v.X = dir != 0 ? dir * Speed : Mathf.MoveToward(v.X, 0, Speed);

        Velocity = v;
        MoveAndSlide();                             // no args, like GDScript 4.x
    }
}
2. C# イベントとしてのシグナル
using Godot;

public partial class Health : Node
{
    // Delegate name MUST end with "EventHandler"; generator creates the event + SignalName.
    [Signal] public delegate void HealthChangedEventHandler(int current, int max);

    private int _hp = 100;

    public void TakeDamage(int amount)
    {
        _hp = Mathf.Max(_hp - amount, 0);
        EmitSignal(SignalName.HealthChanged, _hp, 100);   // type-safe signal name
    }

    public override void _Ready()
    {
        HealthChanged += OnHealthChanged;            // subscribe like a normal C# event
    }

    private void OnHealthChanged(int current, int max) => GD.Print($"HP {current}/{max}");
}
3. C# でシーンをインスタンス化する
public partial class Spawner : Node2D
{
    // Load once; PackedScene is the C# equivalent of preload's result.
    private readonly PackedScene _bullet = GD.Load<PackedScene>("res://bullet.tscn");

    public void Shoot(Vector2 at)
    {
        var b = _bullet.Instantiate<Node2D>();       // typed instantiate
        b.GlobalPosition = at;
        AddChild(b);
    }
}
4. GDScript ノードとの相互運用
public override void _Ready()
{
    Node gd = GetNode("GDScriptNode");
    // Call a GDScript method and read/write its properties dynamically.
    gd.Call("take_damage", 10);
    int score = (int)gd.Get("score");
    gd.Set("score", score + 5);
    // Connect to a GDScript signal by name:
    gd.Connect("died", Callable.From(OnDied));
}

private void OnDied() => GD.Print("entity died");

注意点

  • partial を忘れないでください。 partial がないと Godot のソースジェネレーターがクラスを拡張できず、[Export]/[Signal] で分かりにくいビルドエラーが発生します。
  • メソッドの大文字・小文字やシグネチャを間違えないでください。 C# のオーバーライドは _Ready、_Process(double)、_PhysicsProcess(double) です。PascalCase で、delta は double を使います(GDScript では snake_case と float を使用します)。名前が一致しない場合、メソッドは呼び出されません。
  • [Signal] デリゲートの命名に注意してください。 名前の末尾は EventHandler にする必要があります。エンジンではその接尾辞を除いた名前でシグナルが公開され、SignalName.X と C# の event が生成されます。
  • GD.Print と Console.WriteLine の違いに注意してください。 Godot の出力パネルに表示するには GD.Print/GD.PrintErr を使用します。Console の出力は表示されない場合があります。
  • 値型の構造体に注意してください。 Vector2、Color、Transform2D は構造体です。ローカルコピーを変更してください(var v = Velocity; v.X = ...; Velocity = v;)。Velocity.X を直接編集しても、コンパイルできないか変更が保持されません。
  • .NET ビルドと SDK が必要です。 .NET 以外のエディターでは C# を実行できません。.NET SDK のバージョンが合わない場合や未インストールの場合は、ビルドに失敗します。Godot 4.7 の対象は .NET 8 です。Android などの AOT 対象では、より新しい SDK ツールが必要になる場合があるため、現在のプラットフォーム別エクスポートに関する注意事項を確認してください。
  • QueueFree() と Free() — GDScript と同じルールです。QueueFree() を推奨します。解放後にオブジェクトを使用すると ObjectDisposedException がスローされます。
  • .NET では一部のプラットフォームへのエクスポート方法が異なります(例:Web/モバイルでは追加手順が必要です)。対象プラットフォームの .NET エクスポートに関する注意事項を確認してください。

参考資料

  • エクスポート属性のバリエーション([ExportGroup]、範囲、型付き配列)、await ToSignal(...) を使った非同期処理、Godot.Collections と System コレクションの違い、C# のカスタム Resource、プロジェクトやビルドの設定については、references/csharp-setup-and-interop.md を参照してください。

関連スキル

  • godot-gdscript — これらのパターンに対応する GDScript 版。
  • godot-signals-groups — シグナル/イベントのアーキテクチャ(言語に依存しません)。
  • godot-resources — データリソース、C# の [Export] + Resource パターン。
  • unity-csharp-scripting — Unity の C#。Unity から移行する開発者向け。

コメント