Up to date

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

Les greffons de l'inspecteur

Le dock de l'inspecteur vous permet de créer des widgets personnalisés pour modifier les propriétés par le biais de plugins. Cela peut être utile lorsque vous travaillez avec des types de données et des ressources personnalisés, bien que vous puissiez utiliser cette fonctionnalité pour modifier les widgets de l'inspecteur pour les types intégrés. Vous pouvez concevoir des contrôles personnalisés pour des propriétés spécifiques, des objets entiers, et même des contrôles séparés associés à des types de données particuliers.

Ce guide explique comment utiliser les classes EditorInspectorPlugin et EditorProperty pour créer une interface personnalisée pour les entiers, en remplaçant le comportement par défaut par un bouton qui génère des valeurs aléatoires entre 0 et 99.

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

Le comportement par défaut à gauche et le résultat final à droite.

Configuration de votre plugin

Créez un greffon vide pour démarrer.

Voir aussi

Consultez le guide Création de plugins pour configurer votre nouveau plugin.

Supposons que vous ayez appelé votre dossier de plugins my_inspector_plugin. Si c'est le cas, vous devriez vous retrouver avec un nouveau dossier addons/my_inspector_plugin qui contient deux fichiers : plugin.cfg et plugin.gd.

Comme précédemment, plugin.gd est un script étendant EditorPlugin et vous devez introduire du nouveau code pour ses méthodes _enter_tree et _exit_tree. Pour configurer votre plugin d'inspecteur, vous devez charger son script, puis créer et ajouter l'instance en appelant add_inspector_plugin(). Si le plugin est désactivé, vous devez supprimer l'instance que vous avez ajoutée en appelant remove_inspector_plugin().

Note

Ici, vous chargez un script et non une scène packagée. C'est pourquoi vous devez utiliser new() au lieu de instance().

# 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)

Interagir avec l'inspecteur

To interact with the inspector dock, your my_inspector_plugin.gd script must extend the EditorInspectorPlugin class. This class provides several virtual methods that affect how the inspector handles properties.

To have any effect at all, the script must implement the _can_handle() method. This function is called for each edited Object and must return true if this plugin should handle the object or its properties.

Note

Cela inclus tous les Resource attachés à un objet.

Vous pouvez implémenter quatre autres méthodes pour ajouter des contrôles à l'inspecteur à des positions spécifiques. Les méthodes parse_begin() et parse_end() ne sont appelées qu'une seule fois, respectivement au début et à la fin de l'analyse de chaque objet. Ils peuvent ajouter des contrôles en haut ou en bas de la disposition de l'inspecteur en appelant add_custom_control().

As the editor parses the object, it calls the parse_category() and _parse_property() methods. There, in addition to add_custom_control(), you can call both add_property_editor() and add_property_editor_for_multiple_properties(). Use these last two methods to specifically add EditorProperty-based controls.

# 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

Ajouter une interface pour modifier les propriétés

La classe EditorProperty est un type spécial de Control qui peut interagir avec les objets édités du dock de l'inspecteur. Elle n'affiche rien mais peut accueillir n'importe quel autre nœud de contrôle, y compris des scènes complexes.

Il y a principalement trois parties dans un script héritant de EditorProperty :

  1. Vous devez définir la méthode _init() pour mettre en place la structure des nœuds de contrôle.

  2. You should implement the _update_property() to handle changes to the data from the outside.

  3. Un signal doit être émis à un moment donné pour informer l'inspecteur que le contrôle a modifié la propriété en utilisant emit_changed.

Vous pouvez afficher votre widget personnalisé de deux façons. Utilisez simplement la méthode par défaut add_child() pour l'afficher à droite du nom de la propriété, et utilisez add_child() suivi de set_bottom_editor() pour le positionner sous le nom.

# 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)

En utilisant le code d'exemple ci-dessus, vous devriez être en mesure de créer un widget personnalisé qui remplace le contrôle par défaut SpinBox pour les nombres entiers par un Button qui génère des valeurs aléatoires.