Up to date

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

Erstellen von Plugins

Über Plugins

Ein Plugin ist eine Möglichkeit, dem Editor weitere nützliche Tools hinzuzufügen. Dies kann nur durch GDScript und Standard-Szenen erfolgen, ohne überhaupt den Editor neu starten zu müssen. Im Gegensatz zu Modulen muss kein C++ Programm geschrieben, oder der Editor neu kompiliert werden. Dies macht Plugins zwar weniger leistungsfähig, man kann aber noch immer viel damit anfangen. Solch eine Erweiterung ist ähnlich wie eine Szene, die man erzeugen kann, mit der Ausnahme, daß es mittels eines Skripts die Editor-Funktionalität erweitert.

Dieses Tutorial wird Sie durch die Erstellung von zwei Plugins führen, damit Sie verstehen, wie sie funktionieren, und in der Lage sind, Ihre eigenen zu entwickeln. Das erste ist ein benutzerdefinierter Node, den Sie zu jeder Szene im Projekt hinzufügen können, und das andere ist ein benutzerdefiniertes Dock, das dem Editor hinzugefügt wird.

Erstellen eines Plugins

Bevor es losgeht, erstellen Sie ein neues leeres Projekt wo Sie möchten. Dies wird der Grundstein zum Entwickeln und Testen des Plugins.

Damit der Editor das neue Plugin erkennt, müssen zwei Dateien erstellt werden: eine plugin.cfg zur Konfiguration und ein Skript mit der Funktionalität. Plugins haben einen Standard-Pfad wie addons/plugin_name innerhalb des Projektverzeichnisses. Godot stellt einen Dialog zur Verfügung um diese Dateien zu erzeugen und sie an der richtigen Stelle zu speichern.

Klicken Sie in der Haupt-Toolbar auf das Dropdown-Menü Projekt. Klicken Sie dann auf Projekteinstellungen.... Gehen Sie auf das Plugins-Tab und klicken Sie dann auf den Button Neues Plugin erstellen oben rechts.

Der Dialog wird wie folgt angezeigt:

../../../_images/making_plugins-create_plugin_dialog.webp

Der Platzhaltertext in jedem Feld beschreibt, wie es sich auf die Erstellung der Dateien durch das Plugin und die Werte der Konfigurationsdatei auswirkt.

Um mit dem Beispiel fortzufahren, verwenden Sie die folgenden Werte:

Plugin Name: My Custom Node
Subfolder: my_custom_node
Description: A custom node made to extend the Godot Engine.
Author: Your Name Here
Version: 1.0.0
Language: GDScript
Script Name: custom_node.gd
Activate now: No

Warnung

Das Deaktivieren der Option Activate now? in C# ist immer erforderlich, da das EditorPlugin Skript, wie jedes andere C# Skript, kompiliert werden muss, was das Bauen des Projekts erfordert. Nach dem Bauen des Projekts kann das Plugin im Plugins-Tab der Projekteinstellungen aktiviert werden.

Die Verzeichnisstruktur sollte am Ende so aussehen:

../../../_images/making_plugins-my_custom_mode_folder.webp

Die Datei plugin.cfg ist eine INI-Datei mit Metadaten über Ihr Plugin. Der Name und die Beschreibung helfen den Leuten zu verstehen, was es tut. Ihr Name hilft Ihnen, für Ihre Arbeit zitiert zu werden. Die Versionsnummer hilft anderen, zu erkennen, ob sie eine veraltete Version haben; wenn Sie sich nicht sicher sind, wie Sie die Versionsnummer herausfinden können, lesen Sie Semantic Versioning. Die Hauptskriptdatei teilt Godot mit, was Ihr Plugin im Editor macht, sobald es aktiv ist.

Die Skript-Datei

Bei der Erstellung des Plugins wird der Dialog automatisch das EditorPlugin-Skript für Sie öffnen. Das Skript hat zwei Anforderungen, die Sie nicht ändern können: Es muss ein @tool-Skript sein, sonst wird es nicht richtig im Editor geladen, und es muss von EditorPlugin erben.

Warnung

Neben dem EditorPlugin-Skript muss auch jedes andere GDSkript, das Ihr Plugin verwendet, auch ein Tool sein. Jedes GDScript ohne @tool, das in den Editor importiert wird, verhält sich wie eine leere Datei!

Es ist wichtig, sich mit der Initialisierung und dem Aufräumen von Ressourcen zu befassen. Eine gute Praxis ist es, die virtuelle Funktion _enter_tree() zu verwenden, um Ihr Plugin zu initialisieren und _exit_tree(), um es zu löschen. Glücklicherweise generiert der Dialog diese Callbacks für Sie. Ihr Skript sollte in etwa wie folgt aussehen:

@tool
extends EditorPlugin


func _enter_tree():
    # Initialization of the plugin goes here.
    pass


func _exit_tree():
    # Clean-up of the plugin goes here.
    pass

Dies ist eine gute Vorlage, um neue Plugins zu erstellen.

Ein benutzerdefinierter Node

Manchmal möchten Sie ein bestimmtes Verhalten in vielen Nodes, z.B. in einer benutzerdefinierten Szene oder einem Control, das wiederverwendet werden kann. Die Instanziierung ist in vielen Fällen hilfreich, kann jedoch manchmal umständlich sein, insbesondere wenn Sie sie in vielen Projekten verwenden. Eine gute Lösung hierfür besteht darin, ein Plugin zu erstellen, das einen Node mit einem benutzerdefinierten Verhalten hinzufügt.

Warnung

Nodes, die über ein EditorPlugin hinzugefügt werden, sind "CustomType"-Nodes. Sie funktionieren zwar mit jeder Skriptsprache, haben aber weniger Funktionen als das Skriptklassensystem. Wenn Sie GDScript oder NativeScript schreiben, empfehlen wir, stattdessen Skript-Klassen zu verwenden.

Um einen neuen Node-Typ zu erstellen, können Sie die Funktion add_custom_type() aus der Klasse EditorPlugin verwenden. Diese Funktion kann neue Typen zum Editor hinzufügen (Nodes oder Ressourcen). Bevor Sie jedoch einen Typ erstellen können, benötigen Sie ein Skript, das als Logik für den Typ dient. Dieses Skript muss zwar nicht die Annotation @tool verwenden, kann aber hinzugefügt werden, damit das Skript im Editor läuft.

In diesem Tutorial werden wir eine Schaltfläche erstellen, die eine Nachricht ausgibt, wenn sie angeklickt wird. Dafür brauchen wir ein Skript, das von Button ausgeht. Es könnte auch BaseButton erweitern, wenn Sie das bevorzugen:

@tool
extends Button


func _enter_tree():
    pressed.connect(clicked)


func clicked():
    print("You clicked me!")

Das war's für unseren einfachen Button. Sie können ihn als my_button.gd im Plugin-Ordner speichern. Sie brauchen auch ein 16×16 Icon, das im Szenenbaum angezeigt wird. Wenn Sie keines haben, können Sie das Default-Icon aus der Engine nehmen und es in Ihrem addons/my_custom_node-Ordner als icon.png speichern, oder Sie verwenden das Default-Godot-Logo (preload("res://icon.svg")).

Tipp

SVG images that are used as custom node icons should have the Editor > Scale With Editor Scale and Editor > Convert Icons With Editor Theme import options enabled. This allows icons to follow the editor's scale and theming settings if the icons are designed with the same color palette as Godot's own icons.

../../../_images/making_plugins-custom_node_icon.png

Nun müssen wir ihn als benutzerdefinierten Typ hinzufügen, damit er im Dialog Neuen Node erstellen angezeigt wird. Dazu ändern Sie das Skript custom_node.gd wie folgt:

@tool
extends EditorPlugin


func _enter_tree():
    # Initialization of the plugin goes here.
    # Add the new type with a name, a parent type, a script and an icon.
    add_custom_type("MyButton", "Button", preload("my_button.gd"), preload("icon.png"))


func _exit_tree():
    # Clean-up of the plugin goes here.
    # Always remember to remove it from the engine when deactivated.
    remove_custom_type("MyButton")

Danach sollte das Plugin bereits in der Plugin-Liste in den Projekteinstellungen verfügbar sein. Aktivieren Sie es, wie unter Überprüfen der Ergebnisse beschrieben.

Probieren Sie es dann aus, indem Sie Ihren neuen Node hinzufügen:

../../../_images/making_plugins-custom_node_create.webp

Wenn Sie den Node hinzufügen, können Sie sehen, dass ihm bereits das von Ihnen erstellte Skript angehängt ist. Setzen Sie einen Text auf den Button, speichern Sie die Szene und führen Sie sie aus. Wenn Sie auf den Button klicken, wird in der Konsole ein Text angezeigt:

../../../_images/making_plugins-custom_node_console.webp

Ein benutzerdefiniertes Dock

Manchmal müssen Sie den Editor erweitern und Tools hinzufügen, die immer verfügbar sind. Eine einfache Möglichkeit besteht darin, ein neues Dock mit einem Plugin hinzuzufügen. Docks sind nur Szenen, die auf Control basieren. Sie werden also ähnlich wie normale GUI-Szenen erstellt.

Das Erstellen eines benutzerdefinierten Docks erfolgt genauso wie das Erstellen eines benutzerdefinierten Nodes. Erstellen Sie eine neue Datei plugin.cfg im Ordner addons/my_custom_dock und fügen Sie ihr den folgenden Inhalt hinzu:

[plugin]

name="My Custom Dock"
description="A custom dock made so I can learn how to make plugins."
author="Your Name Here"
version="1.0"
script="custom_dock.gd"

Dann erstellen Sie das Skript custom_dock.gd im gleichen Ordner. Füllen Sie es mit der Vorlage, die wir schon gesehen haben, um einen guten Start zu bekommen.

Da wir versuchen ein neues benutzerdefiniertes Dock hinzuzufügen, müssen wir den Inhalt des Docks erstellen. Dies ist nichts weiter als eine Standard-Godot-Szene: Erstellen Sie einfach eine neue Szene im Editor und bearbeiten diese.

Für ein Editor-Dock muss der Root-Node ein Control oder eine seiner Child-Klassen sein. Für dieses Tutorial können Sie einen einzelne Button erstellen. Der Name des Root-Nodes ist auch der Name, der auf dem Dock-Tab erscheint. Vergessen Sie auch nicht, Ihrem Button etwas Text hinzuzufügen.

../../../_images/making_plugins-my_custom_dock_scene.webp

Speichern Sie diese Szene unter dem Namen my_dock.tscn. Nun müssen wir die Szene, die wir erstellt haben, als Dock in den Editor einfügen. Hierfür können Sie die Funktion add_control_to_dock() aus der Klasse EditorPlugin verwenden.

Sie müssen eine Dock-Position auswählen und das hinzuzufügende Control definieren (das ist die Szene, die Sie gerade erstellt haben). Vergessen Sie nicht, das Dock zu entfernen, wenn das Plugin deaktiviert ist. Das Skript könnte wie folgt aussehen:

@tool
extends EditorPlugin


# A class member to hold the dock during the plugin life cycle.
var dock


func _enter_tree():
    # Initialization of the plugin goes here.
    # Load the dock scene and instantiate it.
    dock = preload("res://addons/my_custom_dock/my_dock.tscn").instantiate()

    # Add the loaded scene to the docks.
    add_control_to_dock(DOCK_SLOT_LEFT_UL, dock)
    # Note that LEFT_UL means the left of the editor, upper-left dock.


func _exit_tree():
    # Clean-up of the plugin goes here.
    # Remove the dock.
    remove_control_from_docks(dock)
    # Erase the control from the memory.
    dock.free()

Beachten Sie, dass das Dock zwar zunächst an der angegebenen Position erscheint, der Benutzer aber seine Position frei ändern und das resultierende Layout speichern kann.

Überprüfen der Ergebnisse

Nun ist es an der Zeit, die Ergebnisse Ihrer Arbeit zu überprüfen. Öffnen Sie die Projekteinstellungen und klicken Sie auf das Plugins-Tab. Ihr Plugin sollte das einzige in der Liste sein.

../../../_images/making_plugins-project_settings.webp

Sie können sehen, dass das Plugin nicht aktiviert ist. Klicken Sie auf die Checkbox Aktivieren, um das Plugin zu aktivieren. Das Dock sollte sichtbar werden, noch bevor Sie das Einstellungsfenster schließen. Sie sollten jetzt ein benutzerdefiniertes Dock haben:

../../../_images/making_plugins-custom_dock.webp

Darüber hinausgehen

Nachdem Sie nun gelernt haben, wie Sie grundlegende Plugins erstellen, können Sie den Editor auf verschiedene Arten erweitern. Mit GDScript können dem Editor viele Funktionen hinzugefügt werden. Es ist eine leistungsstarke Möglichkeit, spezialisierte Editoren zu erstellen, ohne sich mit C++ Modulen befassen zu müssen.

Sie können Ihre eigenen Plugins erstellen, um sich selbst zu helfen, und diese in der Asset-Bibliothek teilen, damit Andere von Ihrer Arbeit profitieren können.

Registrierung von Autoloads/Singletons in Plugins

Es ist möglich, dass sich Editor-Plugins automatisch autoloads registrieren, wenn das Plugin aktiviert wird. Dies beinhaltet auch die Aufhebung der Registrierung des Autoloads, wenn das Plugin deaktiviert wird.

Dies beschleunigt die Einrichtung von Plugins für die Benutzer, da sie nicht mehr manuell Autoloads zu ihren Projekteinstellungen hinzufügen müssen, wenn Ihr Editor-Plugin die Verwendung eines Autoloads erfordert.

Verwenden Sie den folgenden Code, um ein Singleton aus einem Editor-Plugin zu registrieren:

@tool
extends EditorPlugin

# Replace this value with a PascalCase autoload name, as per the GDScript style guide.
const AUTOLOAD_NAME = "SomeAutoload"


func _enter_tree():
    # The autoload can be a scene or script file.
    add_autoload_singleton(AUTOLOAD_NAME, "res://addons/my_addon/some_autoload.tscn")


func _exit_tree():
    remove_autoload_singleton(AUTOLOAD_NAME)