GodotEngineでポケモンずかん作ってみた解説
挨拶
こんにちは、Godot Engine 4.0のβ版を楽しんでいるSaitosです。
今回、動画にもしている「ポケモン図鑑つくってみた」を解説しようと思ったのですが、すでに記事を3回書き直しています…。
理由は、ノードの機能や個々のレイアウトについてを細かく説明すると、あまりにも内容が多いので、無限に時間が過ぎていくんですよね。
なので、かなり掻い摘んで、サンプルファイルを見てもらう流れにしました。
すいません。
目的
Godot EngineのGUIについての情報共有を目的とするため、今回使用した機能を掻い摘んで説明していきます。
GUIの機能は結構強力で、慣れると楽しいので、ぜひ使ってみてください。
ThemeとTypeVariation
まず、Control
ノードにのみ設定できるResource
としてTheme
があります。
横文字ばかりですが、要するにスキンのようなものです。WebでいうところのCSSのようなものです。
Theme
にはDefault Font
を設定でき、このTheme
が設定されたControl
ノード以下の子ノードたちはすべてこのThemeのフォントやデザインが使用されます。
4.0から、ダイナミックフォントではフォントファイルをそのまま使う事ができる上、サイズを変更しても綺麗に描画されるようになりました。
また、Theme
内でType
を追加し、各ノードにType Variation
として割り当てると、そのType
の名前がついたノードは同じ見た目になります。
今回のポケモン図鑑では、Header
とFooter
という名前でTypeを追加して使っています。
使い方として、例えば、Theme
でButton
のスタイルを変更するとボタンはすべて同じデザインになってしまいます。
ボタンが2種類あって、別々のデザインにしたい場合、片方にはTheme Override
を使用してデザインを上書きするような使い方をしなければなりませんでした。
しかしType Variation
を使うことで、1つのTheme
で個別のデザインを設定できるので、とても便利です。
Containerとレイアウト
Container系のノードは、内包するコンテンツを自動でレイアウトする機能を持っています。
これはレスポンシブ対応のため、画面サイズが変わっても、よい見た目をできる限り保つための機能です。
しかし、場合によっては内包されたコンテンツが、都合の良いサイズにならない場合があります。
例えば、VBoxContainer
は、コンテンツを自動的に縦並びにします。
今回のポケモン図鑑でいうと、図鑑のトップ画面はヘッダー・ボディ・フッターの3つの要素で縦並びになっています。
しかし、ヘッダー・フッターは任意のサイズで固定しておきたく、ボディはウィンドウのサイズが変わっても縦に引き伸ばされた状態であってほしいです。
この場合、まずはVBoxContainer
に内包したBody
ノードのプロパティを変更します。
Body
ノードを選択してインスペクタから、Layout > Container Sizing
を開いて、Expand
にチェックを入れます。
すると、ウィンドウのサイズが変わってもぴったりと引き伸ばされた状態になります。
次に、Header
とFooter
のノードですが、これらはサイズを固定しておきたいので、Layout > Custom Minimum size
のX・Y
のサイズを指定します。
今回は縦方向なのでY
の値を任意の値に変更します。
すると、Body
が引き伸ばされた影響で潰されていたHeader
とFooter
ノードですが、入力したサイズで固定されているのがわかります。
Container
で自動レイアウトをした上で、思い通りのサイズを保ちたい場合は、Layout
から調整をすると使いやすくなります。
コンテンツ同士の大きさの比率を設定する
Layout
のContainer Sizing
の下部に、Stretch Ratio
という項目があります。
これは、並んだコンテンツのうち、選択しているコンテンツの大きさの比率の設定です。
例えば、VBoxContainer
に3つのコンテンツが並んでいる場合、デフォルトでは1.0 : 1.0 : 1.0
の比率になっています。
つまり1/3ずつの大きさになっています。
これを、0.5 : 0.5 : 1.0
とすると、下図のようになります。
また、1.0 : 1.0 : 2.0
に設定しても、0.5 : 0.5 : 1.0
と同じ比率になります。
TextureRectとテクスチャの設定
TextureRect
ノードは単純に設定したテクスチャを表示するだけの機能ですが、その表示方法(Stretch Mode)を選ぶことができます。
ストレッチモードを色々変更する場合は、Texture Size Ignore
(テクスチャサイズを無視)にチェックを入れておきます。
テクスチャサイズよりも小さくする場合が多いのですが、テクスチャサイズを無視しないと、最小サイズがテクスチャサイズになるので使いにくくなります。
ポケモン図鑑を作る上で、ほぼすべてのTextureRect
で、Stretch
をSTRETCH_KEEP_ASPECT_CENTERED
に設定しています。
これは、画像のアスペクト比を固定してストレッチした上で、中央揃えにする という設定です。
つまり横幅または縦幅のいずれかが狭まった際に、画像が小さく表示されます。
例えば今回のポケモン図鑑の、取得状態のアイコンは、そのまま画像を表示すると大きいため、マージンを空けつつTextureRect
はCustom Minimum size
のX
を狭めて細長くしています。
これによりアスペクト比が固定になっているので、中央に揃いながら小さく表示され、微調整が簡単にできました。
TextureRectでできないこと
というか、Controlノードを継承している以上、自動レイアウトに逆らえない部分がある ということです。
例えば、ポケモン図鑑のトップ画面で、ポケモンの名前が入ったボタンにポケモンのドット絵アイコンがついています。
このアイコンは若干はみ出ているのですが、自動レイアウトだとはみ出すことができません。(厳密にはできなくないけど、すごくやりづらい)
なので、今回のポケモン図鑑ではTextureRect
ではなくNode2D
のSprite2D
を子ノードとして使用し、レイアウトしました。
すべてをControl
ノードで対応しようとすると、仕様によって対応しづらい箇所が出てくるので、臨機応変に使えるものを使うのがよいかと思います。
Buttonとシグナル
Button
に限らずですが、Control
ノードはフォーカスされたときやマウスが乗ったときなどにシグナルを発行します。
このシグナルを受け取って、何らかの処理をします。
今回のポケモン図鑑では管理用のノードがButton
を動的に複数作って、ポケモン図鑑のトップ画面のリストを作成しています。
その際に、Button
のfocus_entered
とfocus_exited
とpressed
のシグナルにconnect
して、フォーカスされたらボタンの絵を変更し、フォーカスが外れたら絵を戻し、押されたら画面遷移する処理をしています。
Godot Engineではシグナルのやり取りは必ず発生するので、実際のゲーム部分よりもGUIで慣れるとわかりやすいと思います。
特にボタンのpressed
はシグナルで処理する他ないのですが、選択肢がない分、実装方法は限られているので慣れるのにはちょうどいいかと思います。
SubViewportとViewportTexture
SubViewport
は、別のシーンの描画結果をテクスチャとして表示するために使います。
例えば2Dゲームの中に3Dシーンを入れたり、その逆も可能です。
GUIも同様に、GUIの中で、部分的に2Dや3Dのシーンを表示させたい という時に便利です。
今回のポケモン図鑑では、ポケモンを選んだ時に表示されるポケモンのプレビューに使っています。
SubViewport
をViewportTexture
として使用する場合の注意ですが、ViewportTexture
を(シーンツリー上で)参照するノードより上に追加する必要があります。
処理の順番の問題だとは思いますが、エラーが出ますので、回避するために順番にご注意ください。
また、Godot Engine beta7
時点でも、ViwportTexture
を参照すると、ゲーム本体には影響はありませんが、エディタのログに毎フレームVulkan
エラーが出ます。
ひとまずはViewportTexture
を設定せずに開発し、最後に設定してあげるなど、ひと工夫して進めれば大丈夫です。(きっとRCには直る…はず!Issueを投げましょう)
サンプルファイル
本プロジェクトはGithubで公開していますので、汚いプロジェクトファイルですが、よろしければご覧ください。
色々細かな処理のスクリプトやシェーダーも含まれています。
かなり解説を端折って、GUIの機能に特化して記事を書きました。
ダラダラと説明しながら映像で解説している動画もありますので、よろしければどうぞ
さいごに
ポケモン図鑑完成のための作業中、Godot JapanのDiscordコミュニティのメンバーに助けていただきながら完成しました。
2022年12月現在400名を超えて、日本のユーザーも徐々に多くなってきたのを感じます。
今回のアドベントカレンダーも含め、Godotコミュニティとしての活動も緩やかに増えていっていますので、最後までご覧頂いた方で、もしコミュニティが気になった方は、ぜひご参加ください。
Discussion