Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Inspektor-Plugins

Das Inspektor-Dock ermöglicht es Ihnen, benutzerdefinierte Widgets zu erstellen, um Propertys über Plugins zu bearbeiten. Dies kann bei der Arbeit mit benutzerdefinierten Datentypen und Ressourcen von Vorteil sein, obwohl Sie die Funktion auch verwenden können, um die Inspektor-Widgets für Built-in-Typen zu ändern. Sie können benutzerdefinierte Steuerelemente für bestimmte Eigenschaften, ganze Objekte und sogar separate Controls in Verbindung mit bestimmten Datentypen erstellen.

Diese Anleitung erklärt, wie man die Klassen EditorInspectorPlugin und EditorProperty verwendet, um eine benutzerdefinierte Schnittstelle für Integer-Zahlen zu erstellen, die das Default-Verhalten durch einen Button ersetzt, die zufällige Werte zwischen 0 und 99 erzeugt.

../../../_images/inspector_plugin_example.png

Das Default-Verhalten auf der linken Seite und das Endergebnis auf der rechten Seite.

Einrichten Ihres Plugins

Erstellen Sie ein neues leeres Plugin, um loszulegen.

Siehe auch

Siehe die Erstellen von Plugins-Anleitung, um Ihr neues Plugin einzurichten.

Nehmen wir an, Sie haben Ihren Plugin-Ordner my_inspector_plugin genannt. Wenn dies der Fall ist, sollten Sie einen neuen Ordner addons/my_inspector_plugin haben, der zwei Dateien enthält: plugin.cfg und plugin.gd.

Wie zuvor ist plugin.gd ein Skript, das EditorPlugin erweitert, und Sie müssen neuen Code für seine Methoden _enter_tree und _exit_tree einführen. Um Ihr Inspektor-Plugin einzurichten, müssen Sie sein Skript laden, dann die Instanz erzeugen und hinzufügen, indem Sie add_inspector_plugin() aufrufen. Wenn das Plugin deaktiviert ist, sollten Sie die hinzugefügte Instanz durch den Aufruf von remove_inspector_plugin() entfernen.

Bemerkung

Hier laden Sie ein Skript und nicht eine gepackte Szene. Daher sollten Sie new() anstelle von instance() verwenden.

# plugin.gd
@tool
extends EditorPlugin

var plugin


func _enter_tree():
    plugin = preload("res://addons/my_inspector_plugin/my_inspector_plugin.gd").new()
    add_inspector_plugin(plugin)


func _exit_tree():
    remove_inspector_plugin(plugin)

Interaktion mit dem Inspektor

Um mit dem Inspektor-Dock zu interagieren, muss Ihr Skript my_inspector_plugin.gd die Klasse EditorInspectorPlugin erweitern. Diese Klasse bietet mehrere virtuelle Methoden, die beeinflussen, wie der Inspektor mit Propertys umgeht.

Um überhaupt einen Effekt zu haben, muss das Skript die Methode _can_handle() implementieren. Diese Funktion wird für jedes bearbeitete Object aufgerufen und muss true zurückgeben, wenn dieses Plugin das Objekt oder seine Propertys behandeln soll.

Bemerkung

Dies schließt jede Resource ein, die mit dem Objekt verbunden ist.

Sie können vier weitere Methoden implementieren, um dem Inspektor an bestimmten Positionen Controls hinzuzufügen. Die Methoden parse_begin() und parse_end() werden nur einmal am Anfang bzw. am Ende des Parsens für jedes Objekt aufgerufen. Sie können Controls am oberen oder unteren Rand des Inspektor-Layouts hinzufügen, indem sie add_custom_control() aufrufen.

Wenn der Editor das Objekt analysiert, ruft er die Methoden parse_category() und _parse_property() auf. Dort können Sie, zusätzlich zu add_custom_control(), sowohl add_property_editor() als auch add_property_editor_for_multiple_properties() aufrufen. Benutzen Sie diese letzten beiden Methoden, um speziell EditorProperty-basierte Controls hinzuzufügen.

# my_inspector_plugin.gd
extends EditorInspectorPlugin

var RandomIntEditor = preload("res://addons/my_inspector_plugin/random_int_editor.gd")


func _can_handle(object):
    # We support all objects in this example.
    return true


func _parse_property(object, type, name, hint_type, hint_string, usage_flags, wide):
    # We handle properties of type integer.
    if type == TYPE_INT:
        # Create an instance of the custom property editor and register
        # it to a specific property path.
        add_property_editor(name, RandomIntEditor.new())
        # Inform the editor to remove the default property editor for
        # this property type.
        return true
    else:
        return false

Hinzufügen einer Schnittstelle zum Bearbeiten von Propertys

Die Klasse EditorProperty ist ein spezieller Typ von Control, der mit den bearbeiteten Objekten des Inspektor-Docks interagieren kann. Sie zeigt nichts an, kann aber alle anderen Nodes beherbergen, einschließlich komplexer Szenen.

Das Skript besteht aus drei wesentlichen Teilen, die EditorProperty erweitern:

  1. Sie müssen die Methode _init() definieren, um die Struktur der Control-Nodes einzurichten.

  2. Sie sollten die Funktion _update_property() implementieren, um Änderungen an den Daten von außen zu behandeln.

  3. Irgendwann muss ein Signal ausgegeben werden, um den Inspektor darüber zu informieren, daß das Control die Property mit emit_changed geändert hat.

Sie können Ihr eigenes Widget auf zwei Arten darstellen. Verwenden Sie einfach die Default-Methode add_child(), um es rechts vom Namen der Property anzuzeigen, oder verwenden Sie add_child() gefolgt von set_bottom_editor(), um es unterhalb des Namens zu positionieren.

# random_int_editor.gd
extends EditorProperty


# The main control for editing the property.
var property_control = Button.new()
# An internal value of the property.
var current_value = 0
# A guard against internal changes when the property is updated.
var updating = false


func _init():
    # Add the control as a direct child of EditorProperty node.
    add_child(property_control)
    # Make sure the control is able to retain the focus.
    add_focusable(property_control)
    # Setup the initial state and connect to the signal to track changes.
    refresh_control_text()
    property_control.pressed.connect(_on_button_pressed)


func _on_button_pressed():
    # Ignore the signal if the property is currently being updated.
    if (updating):
        return

    # Generate a new random integer between 0 and 99.
    current_value = randi() % 100
    refresh_control_text()
    emit_changed(get_edited_property(), current_value)


func _update_property():
    # Read the current value from the property.
    var new_value = get_edited_object()[get_edited_property()]
    if (new_value == current_value):
        return

    # Update the control with the new value.
    updating = true
    current_value = new_value
    refresh_control_text()
    updating = false

func refresh_control_text():
    property_control.text = "Value: " + str(current_value)

Mit dem obigen Beispielcode sollten Sie in der Lage sein, ein benutzerdefiniertes Widget zu erstellen, um das Default-Control SpinBox für Integer-Zahlen durch einen Button zu ersetzen, der Zufallswerte generiert.