2026-10-07

Godot でデバッグ中に This control can't grab focus という警告ログが出る

一般的な原因と対処法

警告ログの例

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 件のコメント:

コメントを投稿