LEFログ:学習記録ノート

leflog: 学習の記録をどんどんアップしていきます

【csharp】C#でGodotのチュートリアルを進める場合の注意点

TL;DR

ファイル名とクラス名を一致させよう

概要

C#を使ってGodotのチュートリアルを進めていたのですが、地味に分かりづらいポイントがあったので解説していきます。

その1: macOSを使う場合はHomebrew経由で.NETをインストールする

初め、Godotの公式ドキュメント通りにMicrosoftの公式のインストーラーから.NETをインストールしたのですが、なぜかターミナルでdotnetコマンドを実行できませんでした。

.zshrcを編集してパスを通しても全く反応せず……。

諦めてbrew経由で.NETをインストールしたところ、難なくdotnetコマンドが実行できるようになりました。

そのため、macOSを利用している方は、brew経由で.NETをインストールすることをオススメします。

formulae.brew.sh

dotnet — Homebrew Formulae

brew install --cask dotnet

その2: ファイル名とクラス名を一致させよう

これが一番詰まったポイントでした。

docs.godotengine.org

初めてのスクリプト作成 — Godot Engine (4.x)の日本語のドキュメント

ドキュメントには次のように書いてあります。

The Script workspace should appear with your new sprite_2d.gd file open and the following line of code:

これに従って何も考えずにファイルを作ると、sprite_2d.csを作成することになります。

さて、この状態でこのページの一番最後のスクリプトを動かすと、Godotくんの画像が動きません。

エディタの画面を開くと次のように表示されます。

  /root/godot/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs:561 - Missing class qualified name for reloading script

また、Debuggerにはこのように表示されます。

E 0:00:00:0373   can_instantiate: Cannot instance script because the associated class could not be found. Script: 'res://sprite_2d.cs'. Make sure the script exists and contains a class definition with a name that matches the filename of the script exactly (it's case-sensitive).
  <C++ Error>    Method/function failed. Returning: false
  <C++ Source>   modules/mono/csharp_script.cpp:2417 @ can_instantiate()

どういうことかというと、サンプルコード内のMySprite2Dが原因でエラーが発生しています。

この部分を最初に作成したファイル名、すなわちsprite_2dにしなければなりません。ファイル名とクラス名を合わせる必要があります。

Before

public partial class MySprite2D : Sprite2D

After

public partial class sprite_2d : Sprite2D

「Make sure the script exists and contains a class definition with a name that matches the filename of the script exactly (it's case-sensitive).」とはそれを意味しているのです。

具体的にどうするのが良い?

例えば上記の例でsprite_2d.csSprite2D.csとしてファイルを作成すると、既存のクラス名と衝突してエラーが発生します。

public partial class Sprite2D : Sprite2Dとなり、明らかにおかしいことがわかります。

しかし、C#ではスネークケースを使用することはあまり無いらしいです。

そのため次のどちらかにする方が良いでしょう。

  • 頭にMyを付けて、ファイル作成時にMySprite2D.cs命名し、クラス名もclass MySprite2Dとする
  • 独自のクラス名を考えて、その名前でファイル名とクラス名を揃える
    • 今回の場合だとRotate.csclass Rotateとか

その3: ターミナル出力

ドキュメントだと分かりにくいですが、ターミナルにHello, worldを出力するためのコード全体はこんな感じです。

コンストラクタを呼んだときに出力しています。

using Godot;

public partial class MySprite2D : Sprite2D
{
    public MySprite2D(){
        GD.Print("Hello, world!");
    }
}

他にもこんな書き方ができます。

using Godot;

public partial class MySprite2D : Sprite2D
{
    public override void _Ready()
    {
        GD.Print("Hello, world!");
    }
}

このあたりの説明は公式ドキュメントの次の箇所に詳しく書かれています。

docs.godotengine.org

C# の基本 — Godot Engine (4.x)の日本語のドキュメント

まとめ

いかがでしたでしょうか?(よくネットで見かける締め方)

C#で開発をおこなう場合は、色々注意すべきポイントがあることを確認できたと思います。特にGodotの開発においてはファイル名とクラス名の一致が重要になります。

もし同じエラーに苦しんでいる方はこの記事を参考にしてみてください!