|
@@ -1,17 +1,17 @@
|
|
|
.. _doc_making_plugins:
|
|
|
|
|
|
-Making Plugins
|
|
|
+Making plugins
|
|
|
==============
|
|
|
|
|
|
-About Plugins
|
|
|
+About plugins
|
|
|
~~~~~~~~~~~~~
|
|
|
|
|
|
A plugin is a great way to extend the editor with useful tools. It can be made
|
|
|
entirely with GDScript and standard scenes, without even reloading the editor.
|
|
|
Unlike modules, you don't need to create C++ code nor recompile the engine.
|
|
|
-While this makes plugins not as powerful, there's still a lot of things you can
|
|
|
-do with them. Note that a plugin is not different from any scene you already
|
|
|
-can make, except that it is made via script to add functionality.
|
|
|
+While this makes plugins less powerful, there's still a lot of things you can
|
|
|
+do with them. Note that a plugin is similar to any scene you can already
|
|
|
+make, except it is created using a script to add functionality.
|
|
|
|
|
|
This tutorial will guide you through the creation of two simple plugins so
|
|
|
you can understand how they work and be able to develop your own. The first
|
|
@@ -24,35 +24,34 @@ Creating a plugin
|
|
|
Before starting, create a new empty project wherever you want. This will serve
|
|
|
as base to develop and test the plugins.
|
|
|
|
|
|
-The first thing you need to do is to create a new plugin that the editor can
|
|
|
-understand as such. For that you need two files: ``plugin.cfg`` for the
|
|
|
+The first thing you need to do is to create a new plugin the editor can
|
|
|
+understand as such. You need two files for that: ``plugin.cfg`` for the
|
|
|
configuration and a custom GDScript with the functionality.
|
|
|
|
|
|
Plugins have a standard path like ``addons/plugin_name`` inside the project
|
|
|
-folder. So create the folder ``my_custom_node`` inside ``addons``. So you'll
|
|
|
-have a directory structure like this:
|
|
|
+folder. For this example, create a folder ``my_custom_node`` inside ``addons``.
|
|
|
+You should end up with a directory structure like this:
|
|
|
|
|
|
.. image:: img/making_plugins-my_custom_mode_folder.png
|
|
|
|
|
|
-To make the ``plugin.cfg`` file, open your favorite text editor with a blank
|
|
|
-file. Godot is not able (yet) to open text files besides scripts, so this must
|
|
|
-be done in an external editor. Add the following structure to your
|
|
|
-``plugin.cfg``::
|
|
|
+Now, open the script editor, click the **File** menu, choose **New TextFile**,
|
|
|
+then navigate to the plugin folder and name the file ``plugin.cfg``.
|
|
|
+Add the following structure to ``plugin.cfg``::
|
|
|
|
|
|
[plugin]
|
|
|
|
|
|
name="My Custom Node"
|
|
|
description="A custom node made to extend the Godot Engine."
|
|
|
author="Your Name Here"
|
|
|
- version="1.0"
|
|
|
+ version="1.0.0"
|
|
|
script="custom_node.gd"
|
|
|
|
|
|
-This is a simple ``ini`` file with metadata about your plugin. You need to set
|
|
|
-up the name and description so users can understand what it does. Add your
|
|
|
-own name so you can be properly credited. A version number is useful so users can see if
|
|
|
-they have an outdated version (if you are unsure on how to come up with
|
|
|
-the version number, check `SemVer <https://semver.org/>`_). And finally a main
|
|
|
-script file to load when your plugin is active.
|
|
|
+This is a simple INI file with metadata about your plugin. You need to set
|
|
|
+the name and description so people can understand what it does. Don't forget
|
|
|
+to add your own name so you can be properly credited. Add a version number
|
|
|
+so people can see if they have an outdated version; if you are unsure on
|
|
|
+how to come up with the version number, check out `Semantic Versioning <https://semver.org/>`_.
|
|
|
+Finally, set the main script file to load when your plugin is active.
|
|
|
|
|
|
The script file
|
|
|
^^^^^^^^^^^^^^^
|
|
@@ -62,8 +61,8 @@ Open the script editor (F3) and create a new GDScript file called
|
|
|
and it has two requirements: it must be a ``tool`` script and it has to
|
|
|
inherit from :ref:`class_EditorPlugin`.
|
|
|
|
|
|
-It's important to deal with initialization and clean-up of resources. So a good
|
|
|
-practice is to use the virtual function
|
|
|
+It's important to deal with initialization and clean-up of resources.
|
|
|
+A good practice is to use the virtual function
|
|
|
:ref:`_enter_tree() <class_Node__enter_tree>` to initialize your plugin and
|
|
|
:ref:`_exit_tree() <class_Node__exit_tree>` to clean it up. You can delete the
|
|
|
default GDScript template from your file and replace it with the following
|
|
@@ -83,27 +82,26 @@ structure:
|
|
|
# Clean-up of the plugin goes here
|
|
|
pass
|
|
|
|
|
|
-This is a good template to use when devising new plugins.
|
|
|
+This is a good template to use when creating new plugins.
|
|
|
|
|
|
A custom node
|
|
|
-~~~~~~~~~~~~~~~~~~~~
|
|
|
+~~~~~~~~~~~~~
|
|
|
|
|
|
-Sometimes you want a certain behavior in many nodes. Maybe a custom scene
|
|
|
-or control that can be reused. Instancing is helpful in a lot of cases but
|
|
|
-sometimes it can be cumbersome, especially if you're using it between many
|
|
|
+Sometimes you want a certain behavior in many nodes, such as a custom scene
|
|
|
+or control that can be reused. Instancing is helpful in a lot of cases, but
|
|
|
+sometimes it can be cumbersome, especially if you're using it in many
|
|
|
projects. A good solution to this is to make a plugin that adds a node with a
|
|
|
custom behavior.
|
|
|
|
|
|
-To create a new node type, you can avail of the function
|
|
|
+To create a new node type, you can use the function
|
|
|
:ref:`add_custom_type() <class_EditorPlugin_add_custom_type>` from the
|
|
|
-:ref:`class_EditorPlugin` class. This function can add new types to the editor,
|
|
|
-be it nodes or resources. But before you can create the type you need a script
|
|
|
-that will act as the logic for the type. While such script doesn't need to have
|
|
|
-the ``tool`` keyword, it is interesting to use it so the user can see it acting
|
|
|
-on the editor.
|
|
|
+:ref:`class_EditorPlugin` class. This function can add new types to the editor
|
|
|
+(nodes or resources). However, before you can create the type, you need a script
|
|
|
+that will act as the logic for the type. While that script doesn't have to use
|
|
|
+the ``tool`` keyword, it can be added so the script runs in the editor.
|
|
|
|
|
|
For this tutorial, we'll create a simple button that prints a message when
|
|
|
-clicked. And for that we'll need a simple script that extends from
|
|
|
+clicked. For that, we'll need a simple script that extends from
|
|
|
:ref:`class_Button`. It could also extend
|
|
|
:ref:`class_BaseButton` if you prefer::
|
|
|
|
|
@@ -117,12 +115,14 @@ clicked. And for that we'll need a simple script that extends from
|
|
|
print("You clicked me!")
|
|
|
|
|
|
That's it for our basic button. You can save this as ``button.gd`` inside the
|
|
|
-plugin folder. You'll also need a 16x16 icon to show in the scene tree. If you
|
|
|
-don't have one, you can grab the default one from the engine, save it in your `addons/my_custom_node` folder as `icon.png` or you use the default Godot logo (`preload("res://icon.png")`).
|
|
|
+plugin folder. You'll also need a 16×16 icon to show in the scene tree. If you
|
|
|
+don't have one, you can grab the default one from the engine and save it in your
|
|
|
+`addons/my_custom_node` folder as `icon.png`, or use the default Godot logo
|
|
|
+(`preload("res://icon.png")`). You can also use SVG icons if desired.
|
|
|
|
|
|
.. image:: img/making_plugins-custom_node_icon.png
|
|
|
|
|
|
-Now we need to add it as a custom type so it shows on the Create New Node
|
|
|
+Now, we need to add it as a custom type so it shows on the **Create New Node**
|
|
|
dialog. For that, change the ``custom_node.gd`` script to the following::
|
|
|
|
|
|
tool
|
|
@@ -138,8 +138,8 @@ dialog. For that, change the ``custom_node.gd`` script to the following::
|
|
|
# Always remember to remove it from the engine when deactivated
|
|
|
remove_custom_type("MyButton")
|
|
|
|
|
|
-With that done, the plugin should already be available in the plugin list at
|
|
|
-Project Settings, so activate it as explained in `Checking the results`_.
|
|
|
+With that done, the plugin should already be available in the plugin list in the
|
|
|
+**Project Settings**, so activate it as explained in `Checking the results`_.
|
|
|
|
|
|
Then try it out by adding your new node:
|
|
|
|
|
@@ -147,21 +147,20 @@ Then try it out by adding your new node:
|
|
|
|
|
|
When you add the node, you can see that it already have the script you created
|
|
|
attached to it. Set a text to the button, save and run the scene. When you
|
|
|
-click the button, you can see a text in the console:
|
|
|
+click the button, you can see some text in the console:
|
|
|
|
|
|
.. image:: img/making_plugins-custom_node_console.png
|
|
|
|
|
|
-
|
|
|
A custom dock
|
|
|
^^^^^^^^^^^^^
|
|
|
|
|
|
-Maybe you need to extend the editor and add tools that are always available.
|
|
|
+Sometimes, you need to extend the editor and add tools that are always available.
|
|
|
An easy way to do it is to add a new dock with a plugin. Docks are just scenes
|
|
|
-based on control, so how to create them is not far beyond your knowledge.
|
|
|
+based on Control, so they are created in a way similar to usual GUI scenes.
|
|
|
|
|
|
-The way to start this plugin is similar to the custom node. So create a new
|
|
|
-``plugin.cfg`` file in the ``addons/my_custom_dock`` folder. And then with
|
|
|
-your favorite text editor add the following content to it::
|
|
|
+Creating a custom dock is done just like a custom node. Create a new
|
|
|
+``plugin.cfg`` file in the ``addons/my_custom_dock`` folder, then
|
|
|
+add the following content to it::
|
|
|
|
|
|
[plugin]
|
|
|
|
|
@@ -171,81 +170,81 @@ your favorite text editor add the following content to it::
|
|
|
version="1.0"
|
|
|
script="custom_dock.gd"
|
|
|
|
|
|
-Then create the script ``custom_dock.gd`` in the same folder. Fill with the
|
|
|
+Then create the script ``custom_dock.gd`` in the same folder. Fill it with the
|
|
|
:ref:`template we've seen before <doc_making_plugins_template_code>` to get a
|
|
|
good start.
|
|
|
|
|
|
Since we're trying to add a new custom dock, we need to create the contents of
|
|
|
-such dock. This is nothing more than a standard Godot scene. So you can create
|
|
|
-a new scene in the editor and start creating it.
|
|
|
+the dock. This is nothing more than a standard Godot scene: just create
|
|
|
+a new scene in the editor then edit it.
|
|
|
|
|
|
-For an editor dock, it is mandatory that the root of the scene is a
|
|
|
-:ref:`Control <class_Control>` or one of its child classes. For this tutorial,
|
|
|
-you can make a single button. The name of the root node will also be the name
|
|
|
-that appears on the dock tab, so be sure to put a descriptive but short one.
|
|
|
-Don't forget to add a text to your button.
|
|
|
+For an editor dock, the root node **must** be a :ref:`Control <class_Control>`
|
|
|
+or one of its child classes. For this tutorial, you can create a single button.
|
|
|
+The name of the root node will also be the name that appears on the dock tab,
|
|
|
+so be sure to give it a short and descriptive name.
|
|
|
+Also, don't forget to add some text to your button.
|
|
|
|
|
|
.. image:: img/making_plugins-my_custom_dock_scene.png
|
|
|
|
|
|
-Save this scene as ``my_dock.tscn``.
|
|
|
-
|
|
|
-Now you need to grab that scene you created and add it as a dock in the
|
|
|
-editor. For this you can rely on the function
|
|
|
+Save this scene as ``my_dock.tscn``. Now, we need to grab the scene we created
|
|
|
+then add it as a dock in the editor. For this, you can rely on the function
|
|
|
:ref:`add_control_to_dock() <class_EditorPlugin_add_control_to_dock>` from the
|
|
|
:ref:`EditorPlugin <class_EditorPlugin>` class.
|
|
|
|
|
|
-The code is straightforward, you need to select a dock position to
|
|
|
-add it and have a control to add (which is the scene you just created). It is
|
|
|
-also important that you remember to **remove the dock** when the plugin is
|
|
|
-deactivated. The code can be like this::
|
|
|
+You need to select a dock position and define the control to add
|
|
|
+(which is the scene you just created). Don't forget to
|
|
|
+**remove the dock** when the plugin is deactivated.
|
|
|
+The script could look like this::
|
|
|
|
|
|
tool
|
|
|
extends EditorPlugin
|
|
|
|
|
|
- var dock # A class member to hold the dock during the plugin lifecycle
|
|
|
+ # A class member to hold the dock during the plugin lifecycle
|
|
|
+ var dock
|
|
|
|
|
|
func _enter_tree():
|
|
|
# Initialization of the plugin goes here
|
|
|
- # First load the dock scene and instance it:
|
|
|
+ # Load the dock scene and instance it
|
|
|
dock = preload("res://addons/my_custom_dock/my_dock.tscn").instance()
|
|
|
|
|
|
- # Add the loaded scene to the docks:
|
|
|
+ # 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 scene from the docks:
|
|
|
- remove_control_from_docks(dock) # Remove the dock
|
|
|
- dock.free() # Erase the control from the memory
|
|
|
+ # Remove the dock
|
|
|
+ remove_control_from_docks(dock)
|
|
|
+ # Erase the control from the memory
|
|
|
+ dock.free()
|
|
|
|
|
|
-While the dock position is chosen when adding it, the user is free to move it
|
|
|
-and save the layout with the dock in any position.
|
|
|
+Note that while the dock will initially appear at its specified position,
|
|
|
+the user can freely change its position and save the resulting layout.
|
|
|
|
|
|
Checking the results
|
|
|
^^^^^^^^^^^^^^^^^^^^
|
|
|
|
|
|
-Now it is the moment to check the results of your work. Open the *Project
|
|
|
-Settings* and click on the *Plugins* tab. Your plugin should be the only on
|
|
|
-the list. If it is not showing, click on the *Update* button at the top right
|
|
|
-corner.
|
|
|
+It's now time to check the results of your work. Open the **Project
|
|
|
+Settings** and click on the **Plugins** tab. Your plugin should be the only one
|
|
|
+on the list. If it is not showing, click on the **Update** button in the
|
|
|
+top-right corner.
|
|
|
|
|
|
.. image:: img/making_plugins-project_settings.png
|
|
|
|
|
|
-At the *Status* column, you can see that the plugin is inactive. So you
|
|
|
-need to click on the status to select *Active*. The dock should be immediately
|
|
|
-visible, even before you close the settings window. You should
|
|
|
-have a custom dock:
|
|
|
+You can see the plugin is inactive on the **Status** column; click on the status
|
|
|
+to select **Active**. The dock should become visible before you even close
|
|
|
+the settings window. You should now have a custom dock:
|
|
|
|
|
|
.. image:: img/making_plugins-custom_dock.png
|
|
|
|
|
|
Going beyond
|
|
|
~~~~~~~~~~~~
|
|
|
|
|
|
-Now that you learned how to make basic plugins, you can extend the editor in
|
|
|
-many nice ways. Many functions can be added to editor on the fly with GDScript,
|
|
|
-it is a powerful way to create special editors without having to delve into C++
|
|
|
-modules.
|
|
|
+Now that you've learned how to make basic plugins, you can extend the editor in
|
|
|
+several ways. Lots of functionality can be added to the editor with GDScript;
|
|
|
+it is a powerful way to create specialized editors without having to delve into
|
|
|
+C++ modules.
|
|
|
|
|
|
-You can make your own plugins to help you and also share them in Godot's Asset
|
|
|
-Library so many people can benefit of your work.
|
|
|
+You can make your own plugins to help yourself and share them in the
|
|
|
+`Asset Library <https://godotengine.org/asset-library/>`_ so that people
|
|
|
+can benefit from your work.
|