特徴

このページでは、C#とGodotの両方で一般的に使用される機能の概要と、それらの併用方法について説明します。

型変換とキャスト

C#は静的に型指定された言語です。したがって、次の操作は実行できません:

var mySprite = GetNode("MySprite");
mySprite.SetFrame(0);

メソッド GetNode()Node インスタンスを返します。この場合は、明示的に目的の派生型 Sprite に変換する必要があります。

このために、C#にはさまざまなオプションがあります。

キャストと型チェック

返されたNodeをSpriteにキャストできない場合は、 InvalidCastException をスローします。失敗しないと確信している場合は、as 演算子の代わりにキャストを使用します。

Sprite mySprite = (Sprite)GetNode("MySprite");
mySprite.SetFrame(0);

AS演算子の使用

NodeをSpriteにキャストできない場合、as 演算子は null を返します。そのため、値型では使用できません。

Sprite mySprite = GetNode("MySprite") as Sprite;
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);

汎用メソッドを使用

この型変換を透過的にするための汎用メソッドも提供されています。

GetNode<T>() は、ノードを返す前にノードをキャストします。ノードを目的の型にキャストできない場合は、InvalidCastException がスローされます。

Sprite mySprite = GetNode<Sprite>("MySprite");
mySprite.SetFrame(0);

GetNodeOrNull<T>()as 演算子を使用し、ノードを目的の型にキャストできない場合は null を返します。

Sprite mySprite = GetNodeOrNull<Sprite>("MySprite");
// Only call SetFrame() if mySprite is not null
mySprite?.SetFrame(0);

IS演算子を使用した型チェック

ノードをSpriteにキャストできるかどうかを確認するには、 is 演算子を使用できます。is 演算子は、ノードをSpriteにキャストできない場合はfalseを返し、できる場合はtrueを返します。

if (GetNode("MySprite") is Sprite)
{
    // Yup, it's a sprite!
}

より高度な型チェックについては、 パターンマッチング<https://docs.microsoft.com/ja-jp/dotnet/csharp/pattern-matching> で調べることができます。

C#シグナル

完全なC#の例については、チュートリアル スクリプトHandling a signalを参照してください。

C#でシグナルを宣言するには、デリゲートの [Signal] 属性を使います。

[Signal]
delegate void MySignal();

[Signal]
delegate void MySignalWithArguments(string foo, int bar);

これらのシグナルは、エディタまたは Connect を持つコードから接続することができます。エディタでシグナルを接続する場合は、新しいシグナルを表示するためにプロジェクトアセンブリを(再)ビルドする必要があります。このビルドは、エディタウィンドウの右上隅にある [ビルド] ボタンをクリックして手動でトリガーできます。

public void MyCallback()
{
    GD.Print("My callback!");
}

public void MyCallbackWithArguments(string foo, int bar)
{
    GD.Print("My callback with: ", foo, " and ", bar, "!");
}

public void SomeFunction()
{
    instance.Connect("MySignal", this, "MyCallback");
    instance.Connect(nameof(MySignalWithArguments), this, "MyCallbackWithArguments");
}

シグナルの発信は EmitSignal メソッドで行われます。

public void SomeFunction()
{
    EmitSignal(nameof(MySignal));
    EmitSignal("MySignalWithArguments", "hello there", 28);
}

シグナル名はいつでも `` nameof`` キーワードで参照できることに注意してください(デリゲート自体に適用されます)。

オブジェクト配列を渡すことで、接続を確立するときに値をバインドできます。

public int Value { get; private set; } = 0;

private void ModifyValue(int modifier)
{
    Value += modifier;
}

public void SomeFunction()
{
    var plusButton = (Button)GetNode("PlusButton");
    var minusButton = (Button)GetNode("MinusButton");

    plusButton.Connect("pressed", this, "ModifyValue", new object[] { 1 });
    minusButton.Connect("pressed", this, "ModifyValue", new object[] { -1 });
}

シグナルは、すべての 組み込み型<https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/built-in-types-table>Godot.Object から派生したクラスのパラメーターとバインド値をサポートします。。したがって、すべての Node または Reference は自動的に互換性がありますが、カスタムデータオブジェクトは Godot.Object またはそのサブクラスの1つから拡張する必要があります。

public class DataObject : Godot.Object
{
    public string Field1 { get; set; }
    public string Field2 { get; set; }
}

最後に、シグナルは AddUserSignal を呼び出すことで作成できますが、シグナルを使用する前に(Connect または EmitSignal を使って)実行する必要があることに注意してください。

public void SomeFunction()
{
    AddUserSignal("MyOtherSignal");
    EmitSignal("MyOtherSignal");
}

Preprocessor defines

Godot has a set of defines that allow you to change your C# code depending on the environment you are compiling to.

注釈

If you created your project before Godot 3.2, you have to modify or regenerate your csproj file to use this feature (compare <DefineConstants> with a new 3.2+ project).

For example, you can change code based on the platform:

    public override void _Ready()
    {
#if GODOT_SERVER
        // Don't try to load meshes or anything, this is a server!
        LaunchServer();
#elif GODOT_32 || GODOT_MOBILE || GODOT_WEB
        // Use simple objects when running on less powerful systems.
        SpawnSimpleObjects();
#else
        SpawnComplexObjects();
#endif
    }

Or you can detect which engine your code is in, useful for making cross-engine libraries:

    public void MyPlatformPrinter()
    {
#if GODOT
        GD.Print("This is Godot.");
#elif UNITY_5_3_OR_NEWER
        print("This is Unity.");
#else
        throw new InvalidWorkflowException("Only Godot and Unity are supported.");
#endif
    }

Full list of defines

  • GODOT is always defined for Godot projects.
  • One of GODOT_64 or GODOT_32 is defined depending on if the architecture is 64-bit or 32-bit.
  • One of GODOT_X11, GODOT_WINDOWS, GODOT_OSX, GODOT_ANDROID, GODOT_HTML5, or GODOT_SERVER depending on the OS. These names may change in the future. These are created from the get_name() method of the :ref:OS <class_OS> singleton, but not every possible OS the method returns is an OS that Godot with Mono runs on.

When exporting, the following may also be defined depending on the export features:

  • One of GODOT_PC, GODOT_MOBILE, or GODOT_WEB depending on the platform type.
  • One of GODOT_ARM64_V8A or GODOT_ARMEABI_V7A on Android only depending on the architecture.
  • One of GODOT_S3TC, GODOT_ETC, or GODOT_ETC2 depending on the texture compression type.
  • Any custom features added in the export menu will be capitalized and prefixed: foo -> GODOT_FOO.