C# features

このページでは、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");
}

プリプロセッサ定義

Godotには、コンパイルする環境に応じてC#コードを変更できる一連の定義があります。

注釈

Godot 3.2より前にプロジェクトを作成した場合、この機能を使用するには、csproj ファイルを変更または再生成する必要があります (<DefineConstants> を新しい3.2+プロジェクトと比較してください)。

たとえば、プラットフォームに基づいてコードを変更できます:

    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
    }

または、コードがどのエンジンにあるかを検出できます。これは、クロスエンジンライブラリを作成するのに役立ちます:

    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
    }

定義の完全なリスト

  • Godotプロジェクトでは、GODOT が常に定義されています。
  • アーキテクチャが64ビットか32ビットかによって、GODOT_64 または GODOT_32 のいずれかが定義されます。
  • One of GODOT_X11, GODOT_WINDOWS, GODOT_OSX, GODOT_ANDROID, GODOT_IOS, 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.

エクスポート する場合、エクスポート機能に応じて以下も定義できます:

  • プラットフォームの種類に応じて、GODOT_PCGODOT_MOBILE、または GODOT_WEB のいずれか。
  • アーキテクチャにのみ依存するAndroid上の GODOT_ARM64_V8A または GODOT_ARMEABI_V7A のいずれか。
  • One of GODOT_ARM64 or GODOT_ARMV7 on iOS only depending on the architecture.
  • Any of GODOT_S3TC, GODOT_ETC, and GODOT_ETC2 depending on the texture compression type.
  • エクスポートメニューに追加されたカスタム機能はすべて大文字になり、接頭辞が付けられます: fooGODOT_FOO

To see an example project, see the OS testing demo: https://github.com/godotengine/godot-demo-projects/tree/master/misc/os_test