making_plugins.rst 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. .. _doc_making_plugins:
  2. Making Plugins
  3. ==============
  4. .. Remove this warning when 2.1 is release
  5. *Important:* This tutorial applies only to the upcoming version 2.1.
  6. About Plugins
  7. ~~~~~~~~~~~~~
  8. A plugin is a great way to extend the editor with useful tools. It can be made
  9. entirely with GDScript and standard scenes, without even reloading the editor.
  10. Unlike modules, you don't need to create C++ code nor recompile the engine.
  11. While this makes plugins not as powerful, there's still a lot of things you can
  12. do with them. Note that a plugin is not different from any scene you already
  13. can make, except that it is made via script to add functionality.
  14. This tutorial will guide you through the creation of two simple plugins so
  15. you can understand how they work and be able to develop your own. The first
  16. will be a custom node that you can add to any scene in the project and the
  17. other will be a custom dock added to the editor.
  18. Creating a plugin
  19. ~~~~~~~~~~~~~~~~~
  20. Before starting, create a new empty project wherever you want. This will serve
  21. as base to develop and test the plugins.
  22. The first thing you need to do is to create a new plugin that the editor can
  23. understand as such. For that you need two files: ``plugin.cfg`` for the
  24. configuration and a custom GDScript with the functionality.
  25. Plugins have a standard path like ``addons/plugin_name`` inside the project
  26. folder. So create the folder ``my_custom_node`` inside ``addons``. So you'll
  27. have a directory structure like this:
  28. .. image:: /img/making_plugins-my_custom_mode_folder.png
  29. To make the ``plugin.cfg`` file, open your favorite text editor with a blank
  30. file. Godot is not able (yet) to open text files besides scripts, so this must
  31. be done in an external editor. Add the following structure to your
  32. ``plugin.cfg``::
  33. [plugin]
  34. name="My Custom Node"
  35. description="A custom node made to extend the Godot Engine."
  36. author="Your Name Here"
  37. version="1.0"
  38. script="custom_node.gd"
  39. This is a simple ``ini`` file with metadata about your plugin. You need to set
  40. up the name and description so users can understand what it does. Add your
  41. own name so you can be properly credited. A version number is useful so users can see if
  42. they have an outdated version (if you are unsure on how to come up with
  43. the version number, check `SemVer <http://semver.org/>`_). And finally a main
  44. script file to load when your plugin is active.
  45. The script file
  46. ^^^^^^^^^^^^^^^
  47. Open the script editor (F3) and create a new GDScript file called
  48. ``custom_node.gd`` inside the ``my_custom_node`` folder. This script is special
  49. and it has two requirements: it must be a ``tool`` script and it has to
  50. inherit from :ref:`class_EditorPlugin`.
  51. It's important to deal with initialization and clean-up of resources. So a good
  52. practice is to use the virtual function
  53. :ref:`_enter_tree() <class_Node__enter_tree>` to initialize your plugin and
  54. :ref:`_exit_tree() <class_Node__exit_tree>` to clean it up. You can delete the
  55. default GDScript template from your file and replace it with the following
  56. structure:
  57. .. _doc_making_plugins_template_code:
  58. .. code-block:: python
  59. tool
  60. extends EditorPlugin
  61. func _enter_tree():
  62. # Initialization of the plugin goes here
  63. pass
  64. func _exit_tree():
  65. # Clean-up of the plugin goes here
  66. pass
  67. This is a good template to use when devising new plugins.
  68. A custom node
  69. ~~~~~~~~~~~~~~~~~~~~
  70. Sometimes you want a certain behavior in many nodes. Maybe a custom scene
  71. or control that can be reused. Instancing is helpful in a lot of cases but
  72. sometimes it can be cumbersome, especially if you're using it between many
  73. projects. A good solution to this is to make a plugin that adds a node with a
  74. custom behavior.
  75. To create a new node type, you can avail of the function
  76. :ref:`add_custom_type() <class_EditorPlugin_add_custom_type>` from the
  77. :ref:`class_EditorPlugin` class. This function can add new types to the editor,
  78. be it nodes or resources. But before you can create the type you need a script
  79. that will act as the logic for the type. While such script doesn't need to have
  80. the ``tool`` keyword, it is interesting to use it so the user can see it acting
  81. on the editor.
  82. For this tutorial, we'll create a simple button that prints a message when
  83. clicked. And for that we'll need a simple script that extends from
  84. :ref:`class_Button`. It could also extend
  85. :ref:`class_BaseButton` if you prefer::
  86. tool
  87. extends Button
  88. func _enter_tree():
  89. connect("pressed", self, "clicked")
  90. func clicked():
  91. print("You clicked me!")
  92. That's it for our basic button. You can save this as ``button.gd`` inside the
  93. plugin folder. You'll also need a 16x16 icon to show in the scene tree. If you
  94. don't have one, you can grab the default one from the engine:
  95. .. image:: /img/making_plugins-custom_node_icon.png
  96. Now we need to add it as a custom type so it shows on the Create New Node
  97. dialog. For that, change the ``custom_node.gd`` script to the following::
  98. tool
  99. extends EditorPlugin
  100. func _enter_tree():
  101. # Initialization of the plugin goes here
  102. # Add the new type with a name, a parent type, a script and an icon
  103. add_custom_type("MyButton", "Button", preload("button.gd"), preload("icon.png"))
  104. func _exit_tree():
  105. # Clean-up of the plugin goes here
  106. # Always remember to remove it from the engine when deactivated
  107. remove_custom_type("MyButton")
  108. With that done, the plugin should already be available in the plugin list at
  109. Project Settings. So activate it and try to add a new node to see the result:
  110. .. image:: /img/making_plugins-custom_node_create.png
  111. When you add the node, you can see that it already have the script you created
  112. attached to it. Set a text to the button, save and run the scene. When you
  113. click the button, you can see a text in the console:
  114. .. image:: /img/making_plugins-custom_node_console.png
  115. A custom dock
  116. ^^^^^^^^^^^^^
  117. Maybe you need to extend the editor and add tools that are always available.
  118. An easy way to do it is to add a new dock with a plugin. Docks are just scenes
  119. based on control, so how to create them is not far beyond your knowledge.
  120. The way to start this plugin is similar to the custom node. So create a new
  121. ``plugin.cfg`` file in the ``addons/my_custom_dock`` folder. And then with
  122. your favorite text editor add the following content to it::
  123. [plugin]
  124. name="My Custom Dock"
  125. description="A custom dock made so I can learn how to make plugins."
  126. author="Your Name Here"
  127. version="1.0"
  128. script="custom_dock.gd"
  129. Then create the script ``custom_dock.gd`` in the same folder. Fill with the
  130. :ref:`template we've seen before <doc_making_plugins_template_code>` to get a
  131. good start.
  132. Since we're trying to add a new custom dock, we need to create the contents of
  133. such dock. This is nothing more than a standard Godot scene. So you can create
  134. a new scene in the editor and start creating it.
  135. For an editor dock, it is mandatory that the root of the scene is a
  136. :ref:`Control <class_Control>` or one of its child classes. For this tutorial,
  137. you can make a single button. The name of the root node will also be the name
  138. that appears on the dock tab, so be sure to put a descriptive but short one.
  139. Don't forget to add a text to your button.
  140. .. image:: /img/making_plugins-my_custom_dock_scene.png
  141. Save this scene as ``my_dock.tscn``.
  142. Now you need to grab that scene you just created and add it as a dock in the
  143. editor. For this you can rely on the function
  144. :ref:`add_control_to_dock() <class_EditorPlugin_add_control_to_dock>` from the
  145. :ref:`EditorPlugin <class_EditorPlugin>` class.
  146. The code is very straightforward, you just need to select a dock position to
  147. add it and have a control to add (which is the scene you just created). It is
  148. also very important that you remember to **remove the dock** when the plugin is
  149. deactivated. The code can be like this::
  150. tool
  151. extends EditorPlugin
  152. var dock # A class member to hold the dock during the plugin lifecycle
  153. func _enter_tree():
  154. # Initialization of the plugin goes here
  155. # First load the dock scene and instance it:
  156. dock = preload("res://addons/my_custom_dock/my_dock.tscn").instance()
  157. # Add the loaded scene to the docks:
  158. add_control_to_dock( DOCK_SLOT_LEFT_UL, dock)
  159. # Note that LEFT_UL means the left of the editor, upper-left dock
  160. func _exit_tree():
  161. # Clean-up of the plugin goes here
  162. # Remove the scene from the docks:
  163. remove_control_from_docks( dock ) # Remove the dock
  164. dock.free() # Erase the control from the memory
  165. While the dock position is chosen when adding it, the user is free to move it
  166. and save the layout with the dock in any position.
  167. Checking the results
  168. ^^^^^^^^^^^^^^^^^^^^
  169. Now it is the moment to check the results of your work. Open the *Project
  170. Settings* and click on the *Plugins* tab. Your plugin should be the only on
  171. the list. If it is not showing, click on the *Update* button at the top right
  172. corner.
  173. .. image:: /img/making_plugins-project_settings.png
  174. At the *Status* column, you can see that the plugin is inactive. So you just
  175. need to click on the status to select *Active*. The dock should be immediately
  176. visible, even before you close the settings window. And now, lo and behold, you
  177. have a custom dock! In just a bit of coding and a simple scene.
  178. .. image:: /img/making_plugins-custom_dock.png
  179. Going beyond
  180. ~~~~~~~~~~~~
  181. Now that you learned how to make basic plugins, you can extend the editor in
  182. many nice ways. Many functions can be added to editor on the fly with GDScript,
  183. it is a powerful way to create special editors without having to delve into C++
  184. modules.
  185. You can make your own plugins to help you and also share them in Godot's Asset
  186. Library so many people can benefit of your work.