Godot トラブルシューティング
想定される「うまく動かない理由」。太字は実際にやらかした内容。
型が認識されない。Could not find type "xxx" in the current scope
シーンスクリプトファイルの先頭にclass_name xxxと書くとグローバルで使えるようになり警告も消える…はずなのだが、たとえその場で動いても、キャッシュをクリアしたりファイルを引っ越したりするタイミングでこのエラーが大量に噴出して大変な目にあうことになる。なのでpreloadを使って明示的にスクリプトファイルのありかを指定したほうが後で楽。IDE上でファイル名を変更したりファイルをフォルダに移動しても勝手に修正してくれる(外部エディタやエクスプローラでそれをやった場合は知らん)。 なお、このケースの場合、preloadの対象はスクリプト(*.gd)である。シーン(*.tscn)じゃないよ!
code:gd
const Bullet = preload("res://player/Bullet.gd")
const BulletEnemy = preload("res://BulletEnemy.gd")
const Enemy = preload("res://enemy/Enemy.gd")
const Player = preload("res://player/Player.gd")
子として挿入した自作シーンの挙動がおかしい。追加したプロパティやシグナルが機能していない。
シーンのインスタンス(鎖マークボタン)ではなく新規シーン(+マークボタン)を使って追加していないか?
表示されない
表示しわすれ。プロパティのvisibileがfalseになっている。
画面外にいる。
原点(0,0)にスポーンさせてしまったよくあるパターン。
あるいは、Follow Viewportの設定を間違えて、画面に固定したいはずのUIをどっかに置いてきてしまったとか。
背景の裏に隠れている。
CanvasLayerのLayerの値は数値が大きいほど手前に来る。
ツリー上のノードの配置順に注意。基本的に上にあるほど奥に表示される。
テクスチャがない。画像のロードに失敗した。
画像が透明である。アニメーションで透明なセルを再生している。
Node2D、Area2D、Marker2D、Raycast2Dなど、もともと表示する機能をもたないノードである。エディタ上では表示されているが、実行時には表示されない。
コリジョンをテストプレイ中に表示させたい場合はメニュー>デバッグ>コリジョン形状を表示。
画面、テクスチャ画像がボケる
プロジェクト設定>一般>レンダリング>テクスチャ>デフォルトのテクスチャフィルタがLinerになっているならNearestにする
反応しない系全般
シグナルが接続されていないか、間違っている
実際、シグナルの接続し忘れはかなり多い。テストのために一度削除してもう一度付け直したりしてシグナルが全部切れてる事に気づかない事多し。
接続した後にいろいろ編集して、発火側と受け側のパラメータの数や型が違ってしまっていることに気づかないパターンも多い。この場合は実行時警告が出るのでちゃんと確認しよう
キャラクターが衝突しても反応しない
衝突イベントが接続されていない。
間違ったイベントに接続している。
Area2Dでは別のArea2Dと重なった場合(area_entered)と???Body2Dが重なった場合(body_entered)で別のシグナルが発火する。body_enteredでArea2Dの衝突をいくら待っても発火されない。
コリジョンノードがないか、形状が登録されていないか間違っている(警告マークが出る)
Rigidbodyの場合max_contacts_reportedがゼロになっている
Rigidbodyでの衝突判定はなるべく避け、かわりにArea2Dに置き換えよう
地形をすり抜ける/ハマる
タイルマップにPhysics Layerがない。形状がおかしい。
コリジョンが無効化されている。敵キャラが倒されたとき、ヒットボックスのかわりにRigidbodyのコリジョンを無効化してしまったときにおこりがち(つまり、これらは別に管理しなければならない)。
透明な何かにひっかかる
地形のコリジョンが正しくない。タイルマップのPhysics Layerの形状を確認。
見えないコリジョンが有効化されている。削除したはずの敵キャラクター等のコリジョンがまだそこに存在している。削除する前にまずコリジョン無効化が必須。
キーボード/PADが反応しない
キー入力を調査する記述がない。記述する場所が間違っている。
Inputの優先順位を確認。たとえば_unhandled_key_inputは_inputよりも優先度が低い。GUIなどにキー入力を取られている可能性がある。 プレイヤーキャラクターの移動用/ポーズボタン/インベントリ操作用…などなど、入力の優先度を決めてしっかり管理する必要がある。
キーイベント名文字列が間違っている。(大文字小文字注意)
プロジェクト設定のキーコンフィグをしていないか、間違っている
UIが反応しない
pressed()シグナルが接続されていないか、間違っている
(マウスが反応しない)GUIより手前になにかのオブジェクトが邪魔をしている
(キーが反応しない)Shortcutが間違っている
大量のボタンのシグナルを手作業で接続するのが大変だ
個人的なGodotエンジンの不満点なのだが、シグナルに発火した元のシーンを判別する情報が含まれないので手作業でシグナルの接続をせざるを得ないのでは?と絶望する人も居るだろう。
そんな場合はカスタムボタンシーンを作る。
1. Buttonを元に新規シーンを作り、以下のスクリプトをアタッチする。
code:gd:CustomButton.gd
extends Button
signal custom_button_downed(id:int)
@export var id:int = 0
func _on_button_down() -> void:
custom_button_downed.emit(id)
2. ボタン自身のbutton_downシグナルを_on_button_downに接続しておく。プロパティのidはボタンごとに変更する。
3. 親シーンを作ってそこにCustomButtonのインスタンスを配置する。
4. 親シーンにスクリプトをアタッチして以下のような記述を書く
code:gd
const CustomButton = preload("res://CustomButton.gd")
...
func _ready() -> void:
for node in get_children(false):
if node is CustomButton:
(node as CustomButton).custom_button_downed.connect(custom_button_downed)
...
func custom_button_downed(id: int) -> void:
print("button pressed:",id)
これでシグナルを手作業で接続せずとも実行時に自動的に接続され、かつ、どのボタンが押されたががidで判別できる。
なおNodeに備わっているeditor_descriptionを利用してそこにボタンIDを記述する方法もあるのだが…そもそもそれはエディタ上でToolTipを表示するためのものなので本来の機能ではない。Node.nameはノード名が変更できなくなり不便だし、Button.textは翻訳されるときに問題が起きるので安易に使うべきではない。
アニメーションが動かない
AnimationPlayerがない。
モーションのラベル文字列が間違っている(大文字小文字、エディタ、スクリプト両方確認)
テクスチャ画像が設定されていない。パスが間違っている。ファイルを消したために行方不明になっている。
(Animation Tree)トランジションの名前が間違っている(エディタ、スクリプト両方確認)
AnimationTreeのトランジション名はAnimationTreeノード上で一覧になっている。
エディタのプロパティ名とスクリプトのプロパティ名では命名規則が違うので注意。大文字小文字、アンダーバーとスペースの違いに注意(命名規則の違いのせいで区別がつかない)。右クリックして「プロパティのパスをコピー」がおすすめ
(AnimationTree)(2D)(BlendSpace)ブレンドカーブが「離散的」になっていない
2D(パラパラ漫画形式)だとブレンドカーブを離散的(「~」じゃなくて「…」みたいなやつ)に設定しないとうまくモーションの移行ができない。
アニメーションが最初のコマから次にうつらない
playを実行していない、もしくはautoplayを設定していない
1描画フレームごとに違うモーションを設定しなおしている(2コマ目に行く前に1コマ目から再生しなおしてしまっている)
アニメの位置がずれたり表示されなかったりする
同じAnimationPlayerの中で、プロパティトラックがあったりなかったりしている
C++の変な警告が出る。Condition "!is_inside_tree()" is true. Returning: false
このエラーは、ツリー上にないNodeシーンに操作が実行できないことを示しています。次のいずれかです。
Nodeはまだ追加されていません(つまり、まだadd_childしていません)。
Nodeは削除されました (queue_freeまたはremove_childのいずれかの理由で)。
シーンの順番が悪さをしている場合がある。
VisibleOnScreenEnabler2Dのツリー上の順番を変えるだけで直ったケースがあった。筆者のケースでは、EffekseerEmitter2DがVisibleOnScreenEnabler2Dより下に並んでいるときに発生し、逆に並べたら出なくなった。また、この動画によるとAudioStreamPlayerでも起きるようだ。動作に影響ない状況であれば、並べ替えを試してみよう。 C++の変な警告が出る。_update_caches: AnimationMixer: ??? has different update modes between some animations which may be blended together. ...
ひとつのAnimationPlayer内にある複数のアニメーション間に一貫性が無いと警告が出るらしい。
???にはアニメーション名が入る(シーンやクラス名ではない)。その名前を使っているアニメーションを洗ってみよう。
C++の変なエラー/警告が出るが、出どころがわからない。
ひとまず再起動してみる。特にアドオンを導入した直後はC++の警告が出やすい。それでも治らないなら…↓
特定のシーンを実行中にそのエラーが出るなら、以下の手順を試す。
まずファイルシステムパネルで問題のシーン(*.tscn)を右クリして「複製」し、複製したシーンを実行しても発生することを確認する。
怪しげな子シーンをひとつずつ消しては実行していく。エラーが出なくなったら最後に消したシーンが原因である。
この方法を試すためにも、各シーンの関係はなるべく「疎」に保つことを心がけよう。
Windowsエクスポートしたいがrceditがないと言われる
エディター設定>エクスポート>Windowsでrcedit.exeのパスを指定する。
実行ファイルのアイコンを設定するのに利用するらしい。
HTML5でエクスポートしたが動かない
ローカルでただhtmlファイルを開いても動かない。サーバーを立てるかしなければならない
Cross domain Isolation が出てるなら.htaccessファイルを書いてアップロードすれば動くようになる(さくらのレンタルサーバで確認)
code:txt:.htaccess
Header set Cross-Origin-Embedder-Policy "require-corp"
Header set Cross-Origin-Opener-Policy "same-origin"
素材がほしい
ここでは主にゲーム開発中の仮データとして使えそうな、無料で手に入るものを列挙する。一応完成版(商用販売物)にそのまま使っても問題なさげなものを挙げているが、素材は可能な限りオリジナルなものに差し替えるのが吉。
2D・ドット絵
そのほか、BOOTHでも「ドット絵素材」等で検索すれば出てくるが有料あるいは権利関係がはっきりしないものが多い。またイラストACやShutterstockでも検索すれば出てくるがこれは絶対に使わないこと。またUnity Asset Storeからの流用は基本的に規約違反である(一部他エンジンでの利用を許可しているアセットもあるので各自確認のこと)。