0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

同一のショートカットを指定して順番に選択できるようにする

Posted at

はじめに

Godotではボタンにショートカットを設定できますが、複数のボタンで同一のショートカットを設定すると、次のように最後に設定されたボタンが反応します。

before.gif

ここでは、ペイントツールでSキーを押すと選択ツールが順番に切り替わるように、次のように同一のショートカットで複数のボタンが順番に反応することを目指します。

after.gif

環境

v4.2.2.stable.official [15073afe3]

ShortcutManager

ショートカットを独自に処理するためにShortcutManagerというクラスを用意します。

shortcut_manager.gd
class_name ShortcutManager
extends Node

signal handled(targets: Array[Variant])

var _shortcut_map = {}


func _shortcut_input(event):
	var event_name = ShortcutManager._get_event_name(event)
	var targets = _shortcut_map.get(event_name)
	if targets == null:
		return

	handled.emit(targets)
	get_viewport().set_input_as_handled()


func add_shortcut(shortcut: Shortcut, target: Variant):
	for event_name in ShortcutManager._get_shortcut_event_names(shortcut):
		if _shortcut_map.has(event_name):
			_shortcut_map[event_name].append(target)
		else:
			_shortcut_map[event_name] = [target]


static func _get_shortcut_event_names(shortcut: Shortcut):
	return shortcut.events.map(_get_event_name)


static func _get_event_name(event: InputEvent):
	return StringName(str(event))

add_shortcutメソッドでショートカットと、それに反応する対象を登録します。
クラスの使用側がショートカットに対するアクションを判別できれば、targetはなんでも構いません。

_shortcut_inputメソッドでイベントが登録されていれば、handledシグナルを発信します。
handledシグナルで送られるのは、トリガーとなったショートカットが紐づけられたすべてのtargetです。

ボタンのリスト

次のようにノードを組み合わせ、

image.png

ButtonListノードに次のようなスクリプトをアタッチすれば、上記のGIFような動作になります。

button_list.gd
extends VBoxContainer

@onready var buttons = [
	$Button1,
	$Button2,
	$Button3,
	$Button4,
	$Button5,
	$Button6,
]

var selected_button: Button = null


func _ready():
	for button in buttons:
		button.toggled.connect(_on_button_toggled.bind(button))
		$ShortcutManager.add_shortcut(button.shortcut, button)
		button.shortcut = null

	$ShortcutManager.handled.connect(_on_shortcut_manager_handled)


func _on_button_toggled(toggled_on: bool, button: Button):
	if toggled_on:
		selected_button = button


func _on_shortcut_manager_handled(targets):
	var index = targets.find(selected_button) + 1
	var button = targets[index % len(targets)]
	button.button_pressed = true

ここで各ボタンにはボタングループとショートカットが設定されており、Toggle Modeがオンになっています。

ShortcutManagerノードには上記のShortcutManagerクラスのスクリプトをアタッチします。ベースノードはNodeです。

おわりに

以上でペイントツールのツールボタンのショートカットのようなものがGodotで実装できます。

GDScriptにも早くジェネリクスが導入されてほしいですね。

0
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?