0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Godotでフォーカスを失わないようにする仕組み

Posted at

前提

本情報はGodot_v4.2.2-stable_win64のものです。

Godotのフォーカスシステム

Godotのフォーカスシステム、便利ですよね。
コントローラー用のゲームだと全てフォーカスベースで操作できるようにしないといけないので、ほとんどデフォルトで動作してくれるのはありがたいです。
https://docs.godotengine.org/ja/4.x/tutorials/ui/gui_navigation.html

困っていること

ただ1つ困ったことがあって、Godotって完全にフォーカスを失ったときに復帰する仕組みがないんですよね。
つまり、どのコンポーネントにもフォーカスが当たってない状態になると、コントローラーでは完全に操作できない状況になります。
どんな時にそうなるかというと…

  • ポーズ画面を開いて、閉じるとき。ポーズ画面のフォーカスが失われて、フォーカスがない状態になる。
  • アイテムショップ画面とかで、アイテムを購入後フォーカスしていたアイテムが削除されたとき。フォーカスしていたアイテムが消えるので、フォーカスがない状態になる。

それぞれのアクション(ポーズ画面を閉じた後、ショップで買い物をした後)に既定のコンポーネントへフォーカスが当たるようなコードを書いてもいいのですが、めんどくさい。

今回の記事はフォーカスが失われた場合に自動で復旧するための仕組みです。

方針

  1. Viewport.gui_focus_changedシグナルでフォーカスの変更を監視し、フォーカスが当たるたび配列にNodeを記録
  2. 毎フレームViewport.gui_get_focus_owner()でフォーカスが当たっているかを監視し、フォーカスが失われていれば1.の配列から取り出してフォーカスを当ててあげる

これだけです。
もっといい方法があれば教えてください。
gui_focus_changedでフォーカスが無くなった時もシグナルが飛んでくると嬉しいのですが、「なにかにフォーカスが当たった時」しかシグナルが発生しないみたいなので、2.で常時監視しています。

コード

以下のコードをFocusManager.mdとか適当な名前を付けて、プロジェクト設定 > 自動読み込みに追加します。

FocusManager.md
extends Node

var focused_node_history = [];

func _ready():
	get_viewport().gui_focus_changed.connect(_on_gui_focus_changed)

func _process(delta):
	_next_focus(); # フォーカスを探索

func _on_gui_focus_changed(node):
	focused_node_history.push_back(node); # フォーカスの履歴に登録

func _next_focus():
	while true:
		var focused_node = get_viewport().gui_get_focus_owner()
		
		if (focused_node != null): break; # フォーカスされているので離脱
		if (focused_node_history.size() == 0): break; # 履歴からフォーカス出来るものが無いので離脱(画面はフォーカスを失う)
		
		var node = focused_node_history.pop_back(); # 前回フォーカスされていたものを取得

		if (node == null): continue; # 既に削除済みなどの理由で取得できなければ次を試す
		if (!node.is_visible_in_tree()): continue; # 画面に表示されていなくても次を一度試す
		
		node.grab_focus();

初回のフォーカスは以下のように自分でフォーカスを当てる必要があります。(どこにフォーカスを当てるべきか分からないので)

func _ready():
	$StartButton.grab_focus()
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?