無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 で、エディター機能を拡張するプラグインを作成する際に用いる EditorPlugin クラスの _handles イベント関数は、新たなノードが選択された際に呼び出されますが、複数選択時に渡される引数のクラスが利用できません。
その現象の確認と、引数と似たデータを取得する対処法について紹介します。

※ GodotEngine 4.3 を使用しています。.NET 版ではありません。
※スクリプトは自己責任でご使用ください。
確認用のプラグインの作成
EditorPlugin の _handles イベント関数で、選択されたノード群の情報を受け取るためには、プラグインを作成・有効化して、作成されたプラグイン用の gd スクリプトに _handles イベント関数をオーバーライドする必要があります。
プラグインを作成するには、メニュー「プロジェクト」→「プロジェクト設定」で表示される「プロジェクト設定」ダイアログの「プラグイン」タブの「新しいプラグインを作成」ボタンを押します。

プラグイン名、サブフォルダー、説明、作者などのプラグインの情報を入力して「作成」ボタンを押します。
「今すぐアクティブ化」チェックがデフォルトでチェックされているので、自動的にプラグインは有効化されます。
手動で有効化する場合は、メニュー「プロジェクト」→「プロジェクト設定」で表示される「プロジェクト設定」ダイアログの「プラグイン」タブのそのプラグインの「有効」をチェックしてください。

addons フォルダ内の指定したサブフォルダにプラグイン用の gd スクリプトが作成されました。

プラグインの設定は、同時に作成された pluguin.cfg で確認できます。
[plugin]
name="ScFitFontSize"
description="選択されているコントロール派生のノードのサイズから、テキスト描画サイズがはみでない、最大のフォントサイズを設定します。"
author="SakuraCrowd"
version=""
script="sc_fit_font_size.gd"
次の章では、作成された sc_fit_font_size.gd ファイルをダブルクリックして編集しまて、 _handles の引数について確認します。
単一・複数ノード選択時の _handles の引数の出力結果
作成したプラグインの gd ファイルを以下のスクリプトで上書きします。
以下のスクリプトでは、 EditorPlugin クラスの _handles イベント関数をオーバーライドして、 システムから _handles を呼び出してもらい、 object (Object クラス)の引数の値を文字列で出力します。
@tool
extends EditorPlugin
## ノードを選択した際に渡される [param object] のクラス名を get_class() から得た文字列で確認します。
## 単一選択では、ノードの名前:<クラス名#数字の番号> でした。
## 複数選択では、<MultiNodeEdit#-数字の番号> でした。
##
## プラグインが特定のタイプのオブジェクト (リソースまたはノード) を編集する場合は、この関数を実装します。
## true を返すと、エディターが関数 _edit と _make_visible を要求したときに呼び出される関数を取得します。
## _forward_canvas_gui_input メソッドと _forward_3d_gui_input メソッドを宣言している場合、これらも呼び出されます。
## 参照: https://docs.godotengine.org/en/stable/classes/class_editorplugin.html#class-editorplugin-private-method-handles
func _handles(object: Object) -> bool:
print("object.get_class() = ", object.get_class(), ", print(object) = ", object)
return false
スクリプトを上書き保存して、プラグインが有効であることを確認します。
※メニュー「プロジェクト」→「プロジェクト設定」で表示される「プロジェクト設定」ダイアログの「プラグイン」タブで「有効」にチェックが入っているか確認できます。
引数の確認ために、「シーン」ドックで、1つのノードをクリックするだけの選択(単一選択)と Shift や Ctrl を押しながらクリックして複数のノードを選択(複数選択)する動作をおこないます。
ノードを単一選択した場合、呼び出された _handles の引数には「ノード名:<クラス名#数字の番号>」が表示されます。
ノードを複数選択した場合、呼び出された _handles の引数には「<MultiNodeEdit#-数字の番号」が表示されます。

object.get_class() = Button, print(object) = OpenButton:
object.get_class() = Button, print(object) = CloseButton:
object.get_class() = RichTextLabel, print(object) = MainTextRichTextLabel:
object.get_class() = RichTextLabel, print(object) = TitleRichTextLabel:
object.get_class() = ColorRect, print(object) = BackGroundColorRect:
object.get_class() = Control, print(object) = CreditScreen:
object.get_class() = Control, print(object) = CreditScreen:
object.get_class() = MultiNodeEdit, print(object) =
object.get_class() = Button, print(object) = OpenButton:
object.get_class() = MultiNodeEdit, print(object) =
※ 最後の <> で囲まれている値はコピーミスのため貼り付けられませんでした。スクリーンショット画像を参照してください。
複数ノード選択時に引数のクラス MultiNodeEdit のパースエラー
以下のスクリプトでは、複数選択時の _handles の object 引数の print 出力で表示された MultiNodeEdit をクラスとして扱い、引数を型変換する処理を追加しました。
※ MultiNodeEdit について検索すると GitHub の godotengine の cpp ファイルが見つかります。 godot/editor/multi_node_edit.cpp at master · godotengine/godot · GitHub
@tool
extends EditorPlugin
## ノードを選択した際に渡される [param object] のクラス名を get_class() から得た文字列で確認します。
## 単一選択では、ノードの名前:<クラス名#数字の番号> でした。
## 複数選択では、<MultiNodeEdit#-数字の番号> でした。
##
## プラグインが特定のタイプのオブジェクト (リソースまたはノード) を編集する場合は、この関数を実装します。
## true を返すと、エディターが関数 _edit と _make_visible を要求したときに呼び出される関数を取得します。
## _forward_canvas_gui_input メソッドと _forward_3d_gui_input メソッドを宣言している場合、これらも呼び出されます。
## 参照: https://docs.godotengine.org/en/stable/classes/class_editorplugin.html#class-editorplugin-private-method-handles
func _handles(object: Object) -> bool:
print("object.get_class() = ", object.get_class(), ", print(object) = ", object)
if object is Button:
pass
if object is MultiNodeEdit:
pass
return false
しかし、このスクリプトを上書き保存すると、以下のパースエラーが発生して、 MultiNodeEdit をクラスとして扱えません。
res://addons/sc_fit_font_size/sc_fit_font_size.gd:22 – Parse Error: Could not find type “MultiNodeEdit” in the current scope.
GD Scirpt のエディターで MultiNodeEdit をクラス名として使った際に出力などに表示されたパースエラー
パースエラーは、Script ワークスペースの下側で確認できます。

また、別のタイミング(再現手順は不明)では、出力下パネルにエラーメッセージとして表示されました。

引数に似たデータを取得するスクリプトによる対処例
前述のとおり、EditorPlugin クラスの _handles イベント関数で渡される現在選択されているノード(オブジェクト?)の情報は、複数選択の場合、MultiNodeEdit 型のオブジェクトにどのようにアクセスしてよいかわからず、プラグインの処理対象になるかを判定して戻り値 (bool) を返せません。
検索すると、同様の問題の回避策として、引数のかわりに、EditorSelection から選択中のノード群を得て、それをもとにプラグインの処理対象かを判定する方法が紹介されていました。
Just hit @strutcode‘s issue. Is there some reason this isn’t exposed? Else we can just add it no?get_editor_interface().get_selection().get_selected_nodes() allows to workaround. Not an ideal interface but workable.
get_editor_interface().get_selection().get_selected_nodes() を使用すると回避策が可能になります。理想的なインターフェイスではありませんが、実用的ですExpose MultiNodeEdit as a scriptable class · Issue #8067 · godotengine/godot-proposals と Google 翻訳
以下は、その回避策の実装例です。
2つの関数のうち、2番目の get_editor_plugin_handles_argument 関数が、先ほどの情報をもとに作成した「選択中のノード群」を得る関数です。
1番目の関数 _handles 関数では、引数の object のかわりに、その関数から得た「選択中のノード群」の情報をもとに、プラグインの処理対象かを判定して戻り値を返します。
@tool
extends EditorPlugin
## Control クラスまたはその派生クラスが選択されたノード群に含まれていれば true を返し、他は false を返します。
## 以下は公式の説明の Google 翻訳です。
## プラグインが特定のタイプのオブジェクト (リソースまたはノード) を編集する場合は、この関数を実装します。
## true を返すと、エディターが関数 _edit と _make_visible を要求したときに呼び出される関数を取得します。
## _forward_canvas_gui_input メソッドと _forward_3d_gui_input メソッドを宣言している場合、これらも呼び出されます。
## 参照: https://docs.godotengine.org/en/stable/classes/class_editorplugin.html#class-editorplugin-private-method-handles
func _handles(object: Object) -> bool:
print("object.get_class() = ", object.get_class(), ", print(object) = ", object)
# 引数と同等と思われる、選択されているノード群の配列を取得します。詳細は呼び出している関数の説明を参照してください。
var selected_nodes: Array[Node] = get_editor_plugin_handles_argument(self)
# 選択されているノード群のノード1つずつのクラス名などを出力します。
for node in selected_nodes:
print("node.get_class() = ", node.get_class(), ", print(node) = ", node)
return false
## _handles の引数とおそらく同等のものを別の方法で取得します。
## 注意: _handles の引数は Object クラスですが、ここで得られるのは Node クラスの配列です。
##
## EditorPlugin _handles イベント関数で渡される引数は、複数のノードなどを選択している場合 MultiNodeEdit と呼ばれる
## アクセスできないクラスのオブジェクトが渡されます。(Godot4.3 2025/02/20 現在)
## その対処法として、別の方法で現在選択されている object 群を取得して、その配列を返します。
## 参照: Expose MultiNodeEdit as a scriptable class · Issue #8067 · godotengine/godot-proposals - https://github.com/godotengine/godot-proposals/issues/8067
static func get_editor_plugin_handles_argument(editor_plugin: EditorPlugin) -> Array[Node]:
var editor_interface: EditorInterface = editor_plugin.get_editor_interface()
var editor_selection: EditorSelection = editor_interface.get_selection()
var selected_nodes: Array[Node] = editor_selection.get_selected_nodes()
return selected_nodes
テスト
プラグインを有効にした状態で、「シーン」ドックで Shift や Ctrl キーを押しながらノードをクリックすることで複数選択してみましょう。
ノードを選択すると _handles 関数が呼ばれ、その時点で選択されている複数のノード群を配列で受け取り、その内容を print 出力できました。
これにより引数のアクセスできない object のデータに似た情報を取得して代替処理を行うことができました。
※ MultiNodeEdit とは異なるため、完全な代替というわけではありません。

object.get_class() = Button, print(object) = OpenButton:
node.get_class() = Button, print(node) = OpenButton:
object.get_class() = MultiNodeEdit, print(object) =
node.get_class() = Button, print(node) = OpenButton:
node.get_class() = RichTextLabel, print(node) = MainTextRichTextLabel:
※ 最後の <> で囲まれている値はコピーミスのため貼り付けられませんでした。スクリーンショット画像を参照してください。
以上で、複数選択時に _handles 関数が呼ばれた際に、どのノードたちが選択されているかを知ることができるようになりました。
#根本的に解決するには、エンジンのほうで MultiNodeEdit クラスを利用できるようにするなどの対応が必要だと思います。
まとめ
無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 で、エディター機能を拡張するプラグインを作成する際に用いる EditorPlugin クラスの _handles イベント関数は、新たなノードが選択された際に呼び出されますが、複数選択時に渡される引数のクラスが利用できません。
今回は、その現象の確認と、引数と似たデータを取得する対処法について紹介しました。
参照サイト Thank You!
- Godot Engine – Free and open source 2D and 3D game engine
- Control — Godot Engine (4.x)の日本語のドキュメント
- Button — Godot Engine (stable) documentation in English
- プラグインの作成 — Godot Engine (4.x)の日本語のドキュメント
- EditorPlugin — Godot Engine (4.x)の日本語のドキュメント
- EditorPlugin — Godot Engine (4.x)の日本語のドキュメント #_handles
- EditorSelection — Godot Engine (4.3)の日本語のドキュメント
- godot/editor/multi_node_edit.cpp at master · godotengine/godot · GitHub
記事一覧 → Compota-Soft-Press
コメント