一般的な原因と対処法
![]() |
| 警告ログの例 |
Godotで特定のコントロールにフォーカスを設定したい時はgrab_focusメソッドを使いますが、コントロールの無効化と併用している場合に"This control can't grab focus"という警告ログが出ることがあります。
対処法としては、grab_focusメソッドを使用しているスクリプトを探して、対象のコントロールがフォーカスできる状態かチェックしてからgrab_focusメソッドを呼び出すようにします。
自分に起きたこと
カードを使うゲームをGodotで作ってデバッグしていると、手札やデッキや捨て札をクリックするわけですが、たまにGodotのエディターに"This control can't grab focus"という警告ログが出ることがありました。
全てが解決した今なら、警告の内容が「Controlがフォーカスできない状態なのでgrab_focusが失敗しました。set_focus_modeを使ってフォーカスの取得を可能にしてください」と言われていることが分かるのですが、当時は「カードの操作には何の問題もないのに、なぜset_focus_modeの話が?」と疑問が深まるだけでした。
警告に「grab focus」とあるので、プロジェクトフォルダを検索してみると、カードUIのスクリプトがヒットしました。カードにマウスカーソルを近づけるとカードを手前に表示する処理で、カードゲームとしては良くある挙動です。
func _on_mouse_entered() -> void:
...
if focus_mode != Control.FOCUS_NONE:
grab_focus()
問題のスクリプトは、mouse_enteredイベントでgrab_focusを呼び出してフォーカスを取得するように実装されていました。事前に「if focus_mode != Control.FOCUS_NONE」でフォーカス可能かチェックしているので、通常はこの対応で問題ないように見えます。
しかし、カードUIの実装を調べてみるとfocus_behavior_recursiveというプロパティも使ってフォーカスの可否を制御していたため、チェックの際はget_focus_mode_with_override というメソッドを使う必要がありました。公式ドキュメントにも、focus_behavior_recursive が影響することもあるのでget_focus_mode_with_override を使うように書いてあります。
Control.focus_mode — Godot Engine (stable) documentation in English
https://docs.godotengine.org/en/stable/classes/class_control.html#class-control-property-focus-mode
以上の調査結果から、以下のようにチェック処理を変更することで解決しました。
func _on_mouse_entered() -> void:
...
if get_focus_mode_with_override() != Control.FOCUS_NONE:
grab_focus()


0 件のコメント:
コメントを投稿