LEFログ:学習記録ノート

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

Godotチュートリアル2Dを完走した感想

サムネイル

サムネ画像

結論

とても良かったです(小並感)

実際のプレイ動画

youtu.be

完成したリポジトリ

チュートリアルで詰まった方はぜひ参考にしてください!*1

github.com

Godotチュートリアル2Dとは?

感想

率直な感想としては、Web開発に近いところがたくさんあるな〜と思いました。

というのも例えばフロントエンド開発において、画面上にアニメーションを表示させるIssueに取り組んだことがあったのですが、その際はD3.jsを使って描画をコントロールしました。timer.teamでは<canvas>: グラフィックキャンバス要素を用いた場面もありました。つまり、ブラウザの画面の動きを制御するというというのがWebフロントエンドの基本的な開発です。

今回のGodotを使った開発も、結局のところ「どうやってゲーム画面を動かすか」というのが大事で、それらが連関して一つの作品が生まれます。画面をクリックしたり、キーボード操作したり、プレイヤー(ユーザー)のアクションに併せて挙動を変えるのが本質です。

大事なポイントとして、(もしアクションゲームを作るならば)物理をしっかり思い出す必要があります。重力、加速度、角速度、ベクトル、ラジアン、当たり判定……とはいえこれらは高校物理の範囲なのでたぶん簡単です。複雑なことをしようとしたら難しくなりそうですが……。

また、チュートリアルを進めるうえで面白かったのが、「シグナル」という概念をGodotでは扱っていることです。特定のイベントが発生したとき、ノードが他のノードにメッセージを発信できる仕組みがシグナルです。この機能によってノード同士の連携(関数呼び出し)が容易になっています。

この概念は、現在進行系で読んでいる『なるほどUnixプロセス』の「第16章 プロセスはシグナルを受信できる」にかなり近似していました。Unixにおけるプロセスが別のプロセスのシグナルを受信できるように、Godotにおいてはノードが別のノードのシグナルを受信できます。

そう考えるとGodotによるゲーム開発は、Unix的な考え方を持っていると言えるかもしれません。

まとめ

Godotを用いたゲーム開発はとても楽しいです。何が一番嬉しいかというと、ゲームエンジンがサクサク動いてストレスが無いのが嬉しい!*2 あとmacOSLinuxでも完全に動くのが嬉しい!*3

Gitとの連携が簡単なのも良いです。また、実はGDScript*4C#を同時に使うこともできちゃいます。すごいですね。

また別の機会に3Dのチュートリアルもやってみようと思います。

*1:キャラクターをゾウのアイコンに変えたものはPull Requestで分けています。

*2:かなり驚異的な軽さです。VSCode並の軽さかも?

*3:UI/UXを細かく調整できるのが助かります。とあるゲームエンジンではmacOSだと文字の大きさを変えられず、かなりストレスが溜まりました

*4:PythonJavaScriptを組み合わた独自言語。VSCodeをエディタにすればDebuggerもFormatterもLSPもCopilotも動きます。

【Godot】The specified Godot executable, 'godot' is invalid. Extension features will not work correctly unless this is fixed. の解決法【VSCode, macOS】

結論

VSCodeの設定で、EditorのPathを次のように設定すればOK!

/Applications/Godot.app/Contents/MacOS/Godot

Godot Tools の Editor Path: Godot 4に上のパスを設定します

解説

VSCodeのGodotの拡張機能を入れたとき、次のようなエラーが発生していました。

Godotが実行できないよというエラー

The specified Godot executable, 'godot' is invalid. Extension features will not work correctly unless this is fixed.

このように書かれているので、Select Godot executableを選択し、Applications内のGodot.appを選択しました。

しかし、更に次のようなエラーが発生しました。

新しいパスでもエラーが発生

VSCode上の設定

The specified Godot executable, '/Applications/Godot.app' is invalid. Extension features will not work correctly unless this is fixed.

次に公式ドキュメントに目を通しました。

github.com

https://github.com/godotengine/godot-vscode-plugin

すると次のような記述を見つけました。

The path to the Godot editor executable. Under Mac OS, this is the executable inside of Godot.app.

えっ、Godot.appの中に実行ファイルがある?

ここで詰まりました。というのも、Godot.appはディレクトリではなく、選択しても下に潜れないからです。

選択してもそれ以上先に進めない

ここでしばらく立ち止まっていましたが……ふと気づきました。ディレクトリのように見えていないだけで、中を確認する方法があるのではないか?

leeaps.com

Macで.appなどの中身を確認する方法 | Leeaps

そして右クリックをすると、次の表示が現れました。「パッケージの内容を表示」をクリックします。

パッケージの内容を表示

あとは実行ファイルを探すだけです。godot.app/Contents/MacOS/Godotと進んでいくと、それらしきファイルを見つけました。

Godotの実行ファイル

最後にこのパスをVSCodeに設定し、無事にエラーが消えました!(/・ω・)/

感想

地味に難しかったです。.app内に潜るのは、macOSに詳しいユーザーなら常識なのかもしれませんが、今まで知らなかったので学びになりました。

あと、もうちょっと拡張機能のドキュメントが親切だったら良かったのに……と思いました。

バグを解決するにあたっては、次の動画がとても役に立ちました。

youtu.be

Godot 4 Visual Studio Code Setup on MacOS - YouTube

VSCodeを使う上ではこのドキュメントも必読です。

docs.godotengine.org

外部テキストエディタの使用 — Godot Engine (4.x)の日本語のドキュメント

また、Redditのこの記事も良かったです。

そして後から気づきましたが、このIssueで似た内容が述べられていました。

このIssueではユーザー設定とWorkspaceの設定が競合してエラーを起こしていたようです。

【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の開発においてはファイル名とクラス名の一致が重要になります。

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

Godotの最初のプロジェクトをGitHubで公開しました

github.com

https://github.com/lef237/godot-rotate-lefzou

ほぼチュートリアル通りですが、ボタンをトグルして自動直進機能を追加しました。

youtu.be

My First Godot Project!!! - YouTube

GDScriptはPythonのようなシンプルな書き味でなかなか良いです。

今迷っているのが、このままGDScriptで進めるか、それともC#を使うかについて。

GDScriptのメリット

  • Godot Engine内のエディタで完結する
  • シンプルで書きやすい
  • コンパイルせずに動く
  • ドキュメントが豊富で情報が多い
  • 他のNodeとの結びつきが分かりやすい
    • Signalsがどこから送信されているかとか

C#のメリット

  • 生成AIのサポートを受けやすい
  • Godot以外の開発にも応用できる
  • 型がある

ひとまず次はC#チュートリアルをやってみて、もっとじっくり比較したいと思います。

youtu.be

Choosing Your Godot Programming Language: C#, C++, GDScript,... - YouTube

ちなみにこんな動画を見つけました。3ヶ月前の公開で10万再生。海外ではGodotが盛り上がっていて良い感じです。

macbook購入時にAppleCare+に加入するかどうかの損益分岐点

結論

macbookを2年~3年以上使う場合にはAppleCare+への加入がオススメ

概要

AppleCare+に加入すると、バッテリー容量が本来の80%を切ったとき、無料でバッテリーを交換できるらしいです。

自分の使っているmacbook proは現在91%(使用開始から約9ヶ月で9%減少)なので、購入してから20ヶ月後、つまり1年8ヶ月後に80%を下回ると推測されます。

そのため、AppleCare+は2年分購入しておくと、バッテリーの減少を気にせず安心して常用できるでしょう。

というのもAppleCare+に入っていない場合、バッテリー交換には43000円掛かります。これはAppleCare+の2年間分の料金とほぼ同じです。

もし同じmacbookを2年以上使い続ける場合は、AppleCare+に加入して損はないでしょう。

出典

support.apple.com

Mac の修理サービス - Apple サポート (日本)

AppleCare+ にご加入で、お使いの製品のバッテリー蓄電容量が本来の 80% 未満に低下している場合は、無償でバッテリーを交換できます。

AppleCare+ にはバッテリーサービス保証が付いていますので、実機検査の結果、お使いの製品のバッテリー蓄電容量が本来の 80% 未満に低下していることが確認できた場合は、無償でバッテリーを交換できます。

MacBook Air または MacBook Pro で「修理サービス推奨」と表示される場合 - Apple サポート (日本)

Mac ノートブックの AppleCare Protection Plan にご加入いただいている場合は、バッテリーが本来の容量の 80 % 未満しか維持できなくなったとき、そのバッテリーを無償で交換いたします。ご加入いただいていない場合は有償での交換となります。

AppleCare製品 - Mac - Apple(日本)

保持容量が本来の容量の80%未満になった場合のバッテリー修理サービス

Mac修理・バッテリー交換の料金と来店予約 - Apple正規修理サービス|ビックカメラ

MacBook バッテリー交換料金 | MacBook Pro (16インチ・15インチ・14インチ・13インチ) 43,000 円(税込)

Chromeの拡張機能「GitHub Prevent Thumbs Down Click」をリリースしました!✨

chromewebstore.google.com

GitHub Prevent Thumbs Down Click

上のリンク先の「GitHub Prevent Thumbs Down Click」という拡張機能をリリースしました!🥳

この拡張機能をリリースした経緯について今回の記事では書いていきます。📝

使い方

使い方は簡単です。まずリンク先に進みます。

Chromeウェブストアの画面

右上の「Chromeに追加」をクリックします。そして、「拡張機能を追加」すると……

無事利用可能になりました!

タブに表示されます

あとは使うだけです。

GitHubのページを開いてみましょう。

このようにリアクションボタンを押す場所があります。

リアクションボタン

Before

拡張機能を追加する前は、バッドボタンが表示されているはずです。

リアクションボタン押下後(Before)

After

拡張機能を追加した後は、バッドボタンが非表示になります。

リアクションボタン押下後(After)

ちなみに、この拡張機能を追加した状態でも既にクリック済みのバッドボタンを解除することができます。

つまり、誤クリックを防ぎつつ、過去の誤クリックに気づくことができます。既にクリック済みのバッドボタンについては表示されるということです。

バッドボタンを非表示にするのではなく、誤クリックを防ぐこと機能にフォーカスしているので、使いやすいと思います。

文章だと分かりづらいかもしれないので、動画にしました!

youtu.be

https://youtu.be/WQ_AITaXxSc

自分の中の小さな困りごと

GitHubはもう何年も使っていますが、ちょっと困っていることがありました。

それは、グッドボタンの隣にバッドボタンがあることです。

この何が怖いのかというと、クリック時に気をつけないと、グッドボタンを押したつもりがバッドボタンを押してしまうことです。意図せず誤クリックしていて、間違ったリアクションを送ってしまう可能性があります。

せめてバッドボタンの代わりにクエスチョンマークになったら良いのに……と思っていましたが、仕様が変わる気配はなさそうでした。

じゃあどうするか……無ければ自分で作ればいい! そんなわけでこの拡張機能を作りました。

拡張機能の製作過程

lef237.hatenablog.com

https://lef237.hatenablog.com/entry/2024/04/17/224946

最近この記事を書いたように、元々はJavaScriptでこの拡張機能を製作していました。

しかし、その過程で「これってもしかしてCSSだけで実現できるのでは?」と気づきました。

該当のDiffがこちらになります。

github.com

https://github.com/lef237/github-prevent-thumbs-down-click/commit/c9d5b97268019c6c0b87f4a5d1c1b0a3732687db

この変更によって、36行あったJavaScriptのコードを全消ししています。

JavaScriptのコード全消し

そして最後に残ったのは、この3行のCSSだけでした。

3行のCSS

はじめのコードでは挙動が安定しなかったのですが、CSSに切り替えてから挙動が安定するようになりました。

JavaScriptだとDOM操作をおこなうため、描画タイミングが遅れてしまう場合がありました。また、何度もクリックしたとき、稀にバッドボタンが表示されてしまう謎の現象も発生していました。細かくデバッグして改善することもできたのですが、どんどんコードが複雑になっていく予感がありました。

シンプルであればあるほど――コード量が少なければ少ないほど――バグは発生しにくくなります。この有名な格言を思い出すことができた開発でした。

Chromeウェブストアでの公開について

拡張機能Chromeウェブストアで公開するには登録料が必要です。これは、5ドルを最初に1回だけ支払うだけで大丈夫です。年会費を取られないので嬉しいです。

5ドルの登録料(1回のみ)

(円安で774円だったのでそれはちょっと苦しかったです……為替……)

おわりに

この拡張機能GitHubで公開しています。またMITライセンスとなります。

github.com

https://github.com/lef237/github-prevent-thumbs-down-click

コードが単純すぎてちょっと恥ずかしいかも

もしバグなどありましたらお気軽にIssueやPull Requestを立てて頂けると嬉しいです!

CSSを決めるとコードがシンプルになる

今個人のプロジェクトとしてChrome拡張機能を作っているのだけど、書いていたJavaScriptのコードを全消しした。

理由としては、全く同じ機能をCSSのみで実装できることに気づいたからである。36行もあったJavaScriptのコードが、3行のCSSに収まった。これはとても気持ちいい。

これと同じことが timer.team の開発でもあって、例えば一時停止中に数字が点滅するアニメーションはCSSで実装している。

クライアントサイドをプログラミングをしていると、ついついJavaScriptでDOM操作して力技で画面を書き換えたくなるけど、これは大変だしバグも生みかねない。CSSに頼れるときはCSSに頼ったほうが安全だし、動作も安定するし、保守性も高いことを改めて感じたレフ蔵であった。

作ってる拡張機能は金曜日辺りに公開できるといいけど、できるかな……

追記(2024-04-26):拡張機能を公開しました!

Chromeの拡張機能「GitHub Prevent Thumbs Down Click」をリリースしました!✨ - LEFログ:学習記録ノート