どうも。仕事と育児の合間をぬって、Godotについて勉強してるがんたんです。
マジでGodotについては初心者だったので、キホンの「キ」から学ぼうと思い、ちょうどUdemyがセール中だったのでGodot関連の講座をいくつか取得してみました。
本日は、その簡単な紹介と、チュートリアルを通じて私が感じたGodotの感動ポイントをまとめてみました。Godot愛が溢れてしまって無意味に長文になってます。すみません.
どんな講座を取得したのか
具体的には、以下の2つの講座です。(セールだったので合わせて5,000円いかなかったと思います。Udemyはほぼ毎月セール(90%オフとかざら)してるので、絶対にセール中にしか講座を買わないようにしたほうがいいです)
このうち、まだ完了させたのは上段の「Complete Godot 2D」のみですが、そこから得られた知識だけでも、シンプルな2Dゲームならマジで作れちゃいそうな気がしてきたので、改めて「Godot、最高!」と思いました。
いずれ時間ができたら下段の「Master Mobile Game Development with Godot 4」の方も進めてみます。
……で、チュートリアルを1つ終えたら改めてGodotの素敵なところが見えてきたので、以下にいくつかまとめて紹介してみようと思います。(講座の内容を紹介するというより、私が個人的に感動したGodotの仕様について紹介していく感じです)
2Dシーンと3Dシーンが完全に別扱いなのが分かりやすい
Godotを触って真っ先に「いいな〜」と思ったのは、2Dシーンと3Dシーンの編集画面が別々であり、互いに干渉しないことです。
例えばUnityでは、3Dオブジェクトと2Dオブジェクトは基本的に同一シーン内に配置されるため、エディターでの編集時に両者が重なり合っているとうまく選択できなかったり、見づらかったりしてストレスかかるんですよね。
編集画面を完全に分けることで、そういうことが予め起こらないようになってるのはすごくいいなーと思いました。
それに、私は2Dゲームを作ることが多いのですが、そういう時って「3D」の表示ってほぼ見ることないので、普段は意識すらしたくないっていうのもあります。
非同期の仕組みがGDScriptに組み込まれてるのがいい
Unity(C#)で非同期処理をやるにはいくつかやり方がありますが、私は「UniTask」が好きです。
UniTask自体はとてもよいプロダクトです。
お仕事や自分のタイトルなどで、いつもありがたく使わせてもらっています。大感謝です。
……しかし、ですね。
これはC#やUnityの特性上仕方ないことではあるのですが……。
「コード内でUniTaskが呼び出せるように正しくセッティングする」のが、毎回面倒なんですよね……。
いつもプロジェクトの初期構築時に「あれ、asmdefの設定ってどうやるんだっけ?」と思い出さなければならず、地味にストレスでした。
その点、Godotはなんのセッティングもなしに、「await なんらかのオブジェクト.なんらかのsignal」とするだけで、そのシグナルが発火するまで待機できるんですよね。(または「await なんらかの非同期メソッド」とすることもできます。)
残念ながらCancellationTokenの仕組みまでは提供されてないようですが、そういう細かい制御を行いたい部分は「GDTask(GodotでUniTaskライクなことができるようになるOSS)を使ってC#で書く」という選択肢も残されているのが、またGodotのいいところですね。
(なんらかの形で、キャンセルも含めてGDScriptだけで完結できないかは、まだ模索中)
@onready アノテーションが便利過ぎて開発爆速になる予感
Godot(GDScript)における代表的なアノテーションには、以下のようなものがあります。(私が使ったことのあるやつだけ)
@export
- 変数を外部に公開する
- つまりインスペクタに表示されてそこから編集できるようになる
- Unityの「public」や「[SerializeField]」に相当
- 変数を外部に公開する
@onready var hoge = $参照したいオブジェクトのツリー内でのパス
- _ready()メソッド内で初期化処理をしなくても、勝手に初期化してくれる
- しかもツリー内のパスは自動で候補を表示してくれるのでそこから選択するだけ
このうち「@onready
」がめちゃくちゃ便利すぎて、感動しました。
Unity(C#)の時みたいに「publicな変数定義して、ヒエラルキーからインスペクターにドラッグアンドドロップして他オブジェクトの参照を取る」みたいなことをしなくて済むようになります。
……もうね、年取ってくると目が弱ってきているので、あの作業、本当に辛いのよね。
描画順の考え方(2D)が非常にシンプル(な気がする)
Godot(2D)の描画順の考え方は、シンプルです。(と個人的には思います)
影響するのは、以下の2つだけ。
- CanvasItemのZIndexの値(大きい方が描画優先度高)
- シーンツリー上の並び順(下にいる方が描画優先度高。同一ZIndexのオブジェクト同士にのみ影響)
まずは「CanvasItemのZIndex」がチェックされて、同じ「ZIndexの値」だったオブジェクト同士に限り、「シーンツリーの並び順」がチェックされるという感じです。
先述の通り、2Dと3Dが明確に区別されているので、そもそもNode2DのTransform.Position内には「Z成分」がありません。
Unityでは、
- RendererのSortingOrder
- Transform.positionのz成分
- ヒエラルキーの並び順
- SortingLayer
などなど、軽く思い出しただけでも4つも描画優先度に関係するパラメータがあり、このへんの考え方をきちんと整理して開発に着手しないと後々どんどん、どんな設定が正解なのかがわからなくなる、という罠があります。
その点、Godotでは、一般的な2Dゲームを作る際には、上記2つのパラメータだけ意識すればいいので、描画順の設定に頭を悩ませることが少ないように思います。
イベント処理(signal)が作りやすい
例えばButtonを押した時に動作する処理を作りたいとします。
Unity(C#)では、
- まずイベント処理の受け手となるメソッドを作成
- インスペクター上でドラッグアンドドロップして紐付け
- プルダウンの中から目的のメソッドを探し出して結びつける
というわりと面倒な3段階の操作が必要になります。
しかしGodotでは、
- Buttonの「pressed」シグナルをインスペクター上でダブルクリック
- 紐付けしたいスクリプトを選んで(基本デフォルトでOK)、「接続」をクリック
のすごくシンプルな2操作をするだけで済みます。
これだけで、自動的にわかりやすい名前のメソッドが作成されて、編集可能になるんですよね。
これ、文章にするとなかなかすごさが伝わらないと思うんですけど、Unityでは「スクリプトエディタとUnityEditorを切り替える度にコンパイルが発生」することを考えると、実時間では1分以上の差が出ると思います。
メソッド名を自動的に作ってくれるのも個人的には超ポイント高し。
というのも、ずぼらな私は、いつも「ボタンを押すと発火するメソッド」の命名をその場その場で考えてしまうので、似たメソッドなのに「OnButtonPressed()」だったり「OnButtonClicked()」だったり、下手すると「OnSelect()」だったりと、バラバラな名前になっちゃうんですよね。
後から読み返す時、そういう表記のブレは非常に気になるものなので、そういうわずらわしさを「そもそも存在しないもの」としてやっつけてくれるGodotさんのことは本当に尊敬してしまいます。
他にも色々あるけれども……
すみません、主に私生活的な意味で、ブログ記事作成に割ける時間にも終わりが来てしまいました。。。
他にも色々あって、とくに2Dゲームを作る時の話なんですけど、Transformのpositionの値と、画面上のピクセル座標の位置が(基本的には)一致してるところも、個人的にはイチオシだったりします。
Unityでは(とくに2DのSpriteにおいては)Transform.positionから取得される値をいちいちScreenPointに変換したりしなきゃいけなくて、けっこう面倒で頭がこんがらがるんですよね。。。
ほんともう、Godotが好きになりすぎて、今後Godotだけを触る人生になりたい感じです。
まだ、1作も完成させてないうえに、開発着手すらしてませんが。笑
チュートリアルをしてみたことで、Godotでできることの具体的なイメージが固まってきたので、そろそろ1作、シンプルな習作をどこかで作って発表してみたいなー、なんて思っている今日この頃です。
アイデアだけは、いくつも持ってます。
というわけで、今回はこのへんで。
また次の記事でお会いしましょう!
(……はぁ〜、たくさんキーボードたたけてスッキリした!)
コメント