インスペクタプラグイン

インスペクタドックは、プロパティを編集するための独自のウィジェットを作成するカスタムプラグインをサポートしています。このチュートリアルでは、class_EditorInspectorPlugin および class_EditorProperty クラスを使用して、カスタム値エディタを作成する例を使用して、このようなプラグインを作成する方法を説明します。

セットアップ

Just like プラグインの作成, we start out by making a new plugin, getting a plugin.cfg file created, and start with our class_EditorPlugin. However, instead of using add_custom_node or add_control_to_dock we'll use add_inspector_plugin.

tool extends EditorPlugin

var plugin: EditorInspectorPlugin

func _enter_tree():
    # EditorInspectorPlugin is a resource, so we use `new()` instead of `instance()`.
    plugin = preload("res://addons/MyPlugin/MyInspectorPlugin.gd").new()
    add_inspector_plugin(plugin)

func _exit_tree():
    remove_inspector_plugin(plugin)

EditorInspectorPlugin

To actually connect into the Inspector, we create a class_EditorInspectorPlugin class. This script provides the "hooks" to the inspector. Thanks to this class, the editor will call the functions within the EditorInspectorPlugin while it goes through the process of building the UI for the inspector. The script is used to check if we should enable ourselves for any class_Object that is currently in the inspector (including any class_Resource that is embedded!).

Once enabled, EditorInspectorPlugin has methods that allow for adding class_EditorProperty nodes or just custom class_Control nodes to the beginning and end of the inspector for that class_Object, or for overriding or changing existing property editors.

# MyInspectorPlugin.gd

extends EditorInspectorPlugin

func can_handle(object):
    # Here you can specify which object types (classes) should be handled by
    # this plugin. For example if the plugin is specific to your player
    # class defined with `class_name MyPlayer`, you can do:
    # `return object is MyPlayer`
    # In this example we'll support all objects, so:
    return true

func parse_property(object, type, path, hint, hint_text, usage):
    # We will handle properties of type integer.
    if type == TYPE_INT:
        # Register *an instance* of the custom property editor that we'll define next.
        add_property_editor(path, MyIntEditor.new())
        # We return `true` to notify the inspector that we'll be handling
        # this integer property, so it doesn't need to parse other plugins
        # (including built-in ones) for an appropriate editor.
        return true
    else:
        return false

EditorProperty

次に、インスタンス化して整数を編集する実際の class_EditorProperty カスタム値エディタを定義します。これはカスタムの class_Control であり、任意の種類の追加ノードを追加して、インスペクタに埋め込む高度なウィジェットを作成できます。

# MyIntEditor.gd
extends EditorProperty
class_name MyIntEditor

var updating = false
var spin = EditorSpinSlider.new()

func _init():
   # We'll add an EditorSpinSlider control, which is the same that the
   # inspector already uses for integer and float edition.
   # If you want to put the editor below the property name, use:
   # `set_bottom_editor(spin)`
   # Otherwise to put it inline with the property name use:
   add_child(spin)
   # To remember focus when selected back:
   add_focusable(spin)
   # Setup the EditorSpinSlider
   spin.set_min(0)
   spin.set_max(1000)
   spin.connect("value_changed", self, "_spin_changed")

func _spin_changed(value):
    if (updating):
        return
    emit_changed(get_edited_property(), value)

func update_property():
    var new_value = get_edited_object()[get_edited_property()]
    updating = true
    spin.set_value(new_value)
    updating = false