属性检查插件

检查器dock支持自定义插件来创建自己的编辑属性的小部件.本教程以创建自定义值编辑器为例,解释了如何使用 :ref:`class_EditorInspectorPlugin`和 :ref:`class_EditorProperty`类来编写此类插件.

场景布置

就像 制作插件 一样,我们先制作一个新的插件,得到一个 plugin.cfg 文件,然后从我们的 EditorPlugin 开始. 但是,我们不使用 add_custom_nodeadd_control_to_dock ,而是使用 add_inspector_plugin .

var plugin


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(编辑器属性面板插件)

为了实际连接到检查器,我们创建一个 :ref:`class_EditorInspectorPlugin`类.这个脚本为检查器提供了 "钩子".多亏了这个类,编辑器在为检查器构建UI的过程中,会调用EditorInspectorPlugin中的函数.该脚本用于检查我们是否应该为当前在检查器中的任何 :ref:`class_Object`(包括任何 :ref:`class_Resource`的嵌入!)启用自己.

一旦启用,EditorInspectorPlugin方法允许添加 :ref:`class_EditorProperty`节点或只是自定义 :ref:`class_Control`节点到该 :ref:`class_Object`的检查器的开头和结尾,或者覆盖或改变现有的属性编辑器.

# 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`自定义值编辑器,我们希望实例化它来编辑整数.这是一个自定义的 :ref:`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