うどんてっくメモ

技術的なメモをまったりと

【Godot】Godotの言語サポートとC#スクリプトを実行してみるメモ

はじめに

Godotで開発するにあたって、いろいろなスクリプトの言語の選択肢があります。その中でもC#が使えるとのことで、基本的な知識を公式ドキュメントをもとに和訳したり抜き出したりしてまとめた記事になります。 詳しい情報や補足事項は公式ドキュメントを参考にしてください。

docs.godotengine.org

また、本記事は以下のバージョンで検証を行なっています。バージョンや時期によっては本記事の説明や機能の仕様が違う場合があるのでご了承ください。

Godotの言語サポート

まずGodot自体はC++製のゲームエンジンです。OSSGitHub上にてコードが公開されています。

GitHub - godotengine/godot: Godot Engine – Multi-platform 2D and 3D game engine

しかし、Godotで開発を行うエンジニアはC++で実装を行う必要はなく、Godotが提供するGDScriptでの実装が基本となります。これは独自のスクリプト言語で、直感的な記述でコンテンツを作り上げるためのGodotの戦略です。

docs.godotengine.org

C++のモジュールを実装し、組み込むことも可能です。公式ではGDScriptを推奨していますが、外部のC++のライブラリを導入したり、パフォーマンスを要するコアな部分を実装する時にはC++での実装もありという形で説明しています。

docs.godotengine.org

そして、Godotのメジャーバージョンが3を迎えて、.NETをサポートしてC#での実装も行えるようになりました。仕組みとしてはMonoによる変換です。 Unityを使われている方は馴染みが深く、Godotを使う際にはC#からやってみるのも良さそうです。まだ新しめの機能なのでドキュメントがやや整ってなかったりするので、少し注意は必要です。

docs.godotengine.org

また、Godotの大きな特徴のひとつがさまざまな言語でのスクリプトによるプラグインが使えることです。公式としては独自のスクリプト言語であるGDScriptをはじめとして、C#C++をサポートしています。そして、非公式なコミュニティではRustやPython、Kotlinといった言語のプラグインも開発されています。次に示すリンクはRustのプラグインです。

github.com

これらのプラグインを実現しているのがGDNaitiveという仕組みです。公式の説明を引用します。

GDNative is a Godot-specific technology that lets the engine interact with native shared libraries at run-time. You can use it to run native code without compiling it with the engine.

docs.godotengine.org

GDNativeによるネイティブコードはGodot上でランタイムでの呼び出しが可能になります。例としてCおよびC++でのGDNativeの実装例が公式ドキュメントで紹介されています。

docs.godotengine.org

GDNativeによるスクリプトをGDNativeLibraryというライブラリの形にビルドし、Godot内で紐付けて参照を行います。コミュニティが開発を行う他の言語のプラグインもこれに則り、GodotのAPIをそれぞれの言語から呼ぶような実装ができるようバインドし、GDNativeLibraryを吐けるようにしたものになります。

以上のように

  • GDScript
  • C++
  • C#
  • GDNative

というスクリプトの選択肢があるのがGodotの言語サポートになります。

GodotのC#サポートと実際に動かしてみる

前項にあるように、Godotにはさまざまな言語で動かす選択肢があります。GDScriptを使う人が多いかと思うので、本記事ではC#で動かすのを試してみます。 本記事を書いているタイミングでは、実装的にMonoの.NET 6.xフレームワークで行われており、C#8.0までの機能が使えるようになっています。 実行には.NET SDKのインストールが必要となります。この時64bit版のGodotであれば当然SDKも64bit版でないといけないのは注意してください。

dotnet.microsoft.com

そして、.NETがサポートされているMono対応バージョンのGodotをインストールします。 公式サイトにわかりやすく用意されているので、そちらから用意するのが手っ取り早いです。

Godot側でスクリプトを実装する際には、言語選択でC#を選びます。サポートされていないGodotだとこの段階で候補に出てこないので注意してください。

テンプレートをもとにスクリプトが作成され、Godot上で表示されます。ログだけ追加したテンプレートのスクリプトを次に示します。

using Godot;
using System;

public class Spatial : Godot.Spatial
{
    // Declare member variables here. Examples:
    // private int a = 2;
    // private string b = "text";

    // Called when the node enters the scene tree for the first time.
    public override void _Ready()
    {
        GD.Print("テスト");
    }

//  // Called every frame. 'delta' is the elapsed time since the previous frame.
//  public override void _Process(float delta)
//  {
//      
//  }
}

これをアタッチしたオブジェクトを用意して「テスト」というログが確認できます。Godotのエディタ上でもサクッとC#をかけるのも特徴です。一定のシンタックスハイライトや ですが、やはりIDEやお気に入りのエディタで実装したいのがエンジニアでしょう。現状Visual StudioやRider、VS Codeといった有名どころの開発はGodotも想定しています。 エディタ設定のMonoのところからExternal Editorを設定すると機能します。ただし、サポートしているエディタが現状だと限定されているので注意してください(Visual StudioVS Code、Rider、ModeDevelopを現状はサポートしています)。

ちなみに余談ですが、RiderだとMarket PlaceにGodotでC#を書くためのプラグインが存在します。導入するとRider側でのGodotの実行やデバッグなどが快適に行えるようになります。

github.com

次にオブジェクトやそのスクリプトへの干渉を行うスクリプトを見てみます。 GDScriptという動的型付けのスクリプト言語で実装する際には型は意識しませんが、C#は静的型付けの言語なので型を明示的に定義する必要があります。

たとえばGetNodeというNodeを参照する基本的なメソッドであれば、ジェネリクスで型を定義します。この辺はUnityを使っている方はGetComponentを意識してもらえればわかるかと思います。 公式ドキュメントで紹介されているGDScriptとC#スクリプトの例を挙げます。

# GDScriptのコード
var mySprite = GetNode("Spatial");
mySprite.SetFrame(0);
Sprite mySprite = GetNode<Sprite>("MySprite");
mySprite.SetFrame(0);

さらなる詳しい文法などは公式ドキュメントを読んでもらえると理解が深まるかと思います。

docs.godotengine.org

おわりに

Godotは多様な実装の手段を用意しており、なかなか柔軟さを感じるゲームエンジンです。 とくにC#はUnityという非常に使用者の多いゲームエンジンでも採用されている言語で、Unityを触っているが、Godotが気になっているというかたも気軽に試すことが可能です。

筆者はGDScript、C#、Rustでの実装を触ってみてますが、シンプルにコンテンツを作る部分ではGDScriptを、コアな実装やパフォーマンスに起因する部分の実装はC#プラグインを、といった使い分けができるのはなかなかおもしろいなと感じました。

また、余談ですがエディタ自体もGodotで実装されているので、最近ではAndroid用のエディタというものがついにベータ版としてリリースされました。スマホスマホのゲームが作れる面白い試みです。

godotengine.org

何かと面白い仕組みがあるGodot、今後も追っていきたいです。