scripting.rst 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. .. _doc_scripting:
  2. Scripting
  3. =========
  4. Introduction
  5. ------------
  6. Before Godot 3.0, the only choice for scripting a game was to use
  7. :ref:`doc_gdscript`. Nowadays, Godot has four (yes, four!) official languages
  8. and the ability to add extra scripting languages dynamically!
  9. This is great, mostly due the large amount of flexibility provided, but
  10. it also makes our work supporting languages more difficult.
  11. The "Main" languages in Godot, though, are GDScript and VisualScript. The
  12. main reason to choose them is their level of integration with Godot, as this
  13. makes the experience smoother; both have very slick editor integration, while
  14. C# and C++ need to be edited in a separate IDE. If you are a big fan of statically typed languages, go with C# and C++ instead.
  15. GDScript
  16. ~~~~~~~~
  17. :ref:`doc_gdscript` is, as mentioned above, the main language used in Godot.
  18. Using it has some positive points compared to other languages due
  19. to its high integration with Godot:
  20. * It's simple, elegant, and designed to be familiar for users of other languages such as Lua, Python, Squirrel, etc.
  21. * Loads and compiles blazingly fast.
  22. * The editor integration is a pleasure to work with, with code completion for nodes, signals, and many other items pertaining to the scene being edited.
  23. * Has vector types built-in (such as Vectors, transforms, etc.), making it efficient for heavy use of linear algebra.
  24. * Supports multiple threads as efficiently as statically typed languages - one of the limitations that made us avoid VMs such as Lua, Squirrel, etc.
  25. * Uses no garbage collector, so it trades a small bit of automation (most objects are reference counted anyway), by determinism.
  26. * Its dynamic nature makes it easy to optimize sections of code in C++ (via GDNative) if more performance is required, all without recompiling the engine.
  27. If you're undecided and have experience with programming, especially dynamically
  28. typed languages, go for GDScript!
  29. VisualScript
  30. ~~~~~~~~~~~~
  31. Beginning with 3.0, Godot offers :ref:`Visual Scripting<doc_what_is_visual_script>`. This is a
  32. typical implementation of a "blocks and connections" language, but
  33. adapted to how Godot works.
  34. Visual scripting is a great tool for non-programmers, or even for experienced developers
  35. who want to make parts of the code more accessible to others,
  36. like game designers or artists.
  37. It can also be used by programmers to build state machines or custom
  38. visual node workflows - for example, a dialogue system.
  39. .NET / C#
  40. ~~~~~~~~~
  41. As Microsoft's C# is a favorite amongst game developers, we have added
  42. official support for it. C# is a mature language with tons of code
  43. written for it, and support was added thanks to
  44. a generous donation from Microsoft.
  45. It has an excellent tradeoff between performance and ease of use,
  46. although one must be aware of its garbage collector.
  47. C# is usually the best choice for companies. The large amount of
  48. programmers familiar with it means less time can be spent learning
  49. Godot and more time can be spent programming with it.
  50. Since Godot uses the `Mono <https://mono-project.com>`_ .NET runtime, in theory
  51. any third-party .NET library or framework can be used for scripting in Godot, as
  52. well as any Common Language Infrastructure-compliant programming language, such as
  53. F#, Boo or ClojureCLR. In practice however, C# is the only officially supported .NET option.
  54. GDNative / C++
  55. ~~~~~~~~~~~~~~
  56. Finally, one of our brightest additions for the 3.0 release:
  57. GDNative allows scripting in C++ without needing to recompile (or even
  58. restart) Godot.
  59. Any C++ version can be used, and mixing compiler brands and versions for the
  60. generated shared libraries works perfectly, thanks to our use of an internal C
  61. API Bridge.
  62. This language is the best choice for performance and does not need to be
  63. used throughout an entire game, as other parts can be written in GDScript or Visual
  64. Script. However the API is clear and easy to use as it resembles, mostly,
  65. Godot's actual C++ API.
  66. More languages can be made available through the GDNative interface, but keep in mind
  67. we don't have official support for them.
  68. Scripting a scene
  69. -----------------
  70. For the rest of this tutorial we'll set up a GUI scene consisting of a
  71. button and a label, where pressing the button will update the label. This will
  72. demonstrate:
  73. - Writing a script and attaching it to a node.
  74. - Hooking up UI elements via signals.
  75. - Writing a script that can access other nodes in the scene.
  76. Before continuing, please make sure to read the :ref:`doc_gdscript` reference.
  77. It's a language designed to be simple, and the reference is short, so it will not take more
  78. than a few minutes to get an overview of the concepts.
  79. Scene setup
  80. ~~~~~~~~~~~
  81. Use the "Add Child Node" dialogue accessed from the Scene tab (or by pressing ``Ctrl+A``) to create a hierarchy with the following
  82. nodes:
  83. - Panel
  84. * Label
  85. * Button
  86. The scene tree should look like this:
  87. .. image:: img/scripting_scene_tree.png
  88. Use the 2D editor to position and resize the Button and Label so that they
  89. look like the image below. You can set the text from the Inspector tab.
  90. .. image:: img/label_button_example.png
  91. Finally, save the scene with a name such as ``sayhello.tscn``.
  92. .. _doc_scripting-adding_a_script:
  93. Adding a script
  94. ~~~~~~~~~~~~~~~
  95. Right click on the Panel node, then select "Attach Script" from the context
  96. menu:
  97. .. image:: img/add_script.png
  98. The script creation dialog will pop up. This dialog allows you to set the
  99. script's language, class name, and other relevant options.
  100. In GDScript the file itself represents the class, so
  101. the class name field will not editable.
  102. The node we're attaching the script to is a panel, so the Inherits field
  103. will automatically be filled in with "Panel". This is what we want, as the
  104. script's goal is to extend the functionality of our panel node.
  105. Finally, enter a path name for the script and select Create:
  106. .. image:: img/script_create.png
  107. The script will then be created and added to the node. You can
  108. see this as an "Open script" icon next to the node in the Scene tab,
  109. as well as in the script property under Inspector:
  110. .. image:: img/script_added.png
  111. To edit the script, select either of these buttons, both of which are highlighted in the above image.
  112. This will bring you to the script editor where a default template will be included:
  113. .. image:: img/script_template.png
  114. There's not much there. The ``_ready()`` function is called when the
  115. node, and all its children, enters the active scene. **Note:** ``_ready()`` is not
  116. the constructor; the constructor is instead ``_init()``.
  117. The role of the script
  118. ~~~~~~~~~~~~~~~~~~~~~~
  119. A script adds behavior to a node. It is used to control how the node functions
  120. as well as how it interacts with other nodes: children, parent, siblings,
  121. and so on. The local scope of the script is the node. In other words, the script
  122. inherits the functions provided by that node.
  123. .. image:: /img/brainslug.jpg
  124. Handling a signal
  125. ~~~~~~~~~~~~~~~~~
  126. Signals are "emitted" when some specific kind of action happens, and they can be
  127. connected to any function of any script instance. Signals are used mostly in
  128. GUI nodes, although other nodes have them too, and you can even define custom
  129. signals in your own scripts.
  130. In this step, we'll connect the "pressed" signal to a custom function.
  131. The editor provides an interface for connecting signals to your scripts. You
  132. can access this by selecting the Button node in the scene tree and then selecting the
  133. "Node" tab. Next, make sure that you have "Signals" selected.
  134. .. image:: img/signals.png
  135. At this point, you could use the visual interface to hook up the "pressed"
  136. signal by double clicking on it and selecting a target node that already has a
  137. script attached to it. But for the sake of learning, we're going to code up the
  138. connection manually.
  139. To accomplish this, we will introduce a function that is probably the most used
  140. by Godot programmers: :ref:`Node.get_node() <class_Node_get_node>`.
  141. This function uses paths to fetch nodes anywhere in the scene, relative to the
  142. node that owns the script.
  143. For the sake of convenience, delete everything underneath ``extends Panel``.
  144. You will fill out the rest of the script manually.
  145. Because the Button and Label are siblings under the Panel
  146. where the script is attached, you can fetch the Button by typing
  147. the following underneath ``extends Panel``:
  148. .. tabs::
  149. .. code-tab:: gdscript GDScript
  150. get_node("Button")
  151. .. code-tab:: csharp
  152. GetNode("Button")
  153. Next, write a function which will be called when the button is pressed:
  154. .. tabs::
  155. .. code-tab:: gdscript GDScript
  156. func _on_button_pressed():
  157. get_node("Label").text = "HELLO!"
  158. .. code-tab:: csharp
  159. public void _OnButtonPressed()
  160. {
  161. var label = (Label)GetNode("Label");
  162. label.Text = "HELLO!";
  163. }
  164. Finally, connect the button's "pressed" signal to ``_ready()`` by
  165. using :ref:`Object.connect() <class_Object_connect>`.
  166. .. tabs::
  167. .. code-tab:: gdscript GDScript
  168. func _ready():
  169. get_node("Button").connect("pressed", self, "_on_button_pressed")
  170. .. code-tab:: csharp
  171. public override void _Ready()
  172. {
  173. GetNode("Button").Connect("pressed", this, nameof(_OnButtonPressed));
  174. }
  175. The final script should look like this:
  176. .. tabs::
  177. .. code-tab:: gdscript GDScript
  178. extends Panel
  179. func _on_button_pressed():
  180. get_node("Label").text = "HELLO!"
  181. func _ready():
  182. get_node("Button").connect("pressed", self, "_on_button_pressed")
  183. .. code-tab:: csharp
  184. using Godot;
  185. // IMPORTANT: the name of the class MUST match the filename exactly.
  186. // this is case sensitive!
  187. public class sayhello : Panel
  188. {
  189. public void _OnButtonPressed()
  190. {
  191. var label = (Label)GetNode("Label");
  192. label.Text = "HELLO!";
  193. }
  194. public override void _Ready()
  195. {
  196. GetNode("Button").Connect("pressed", this, nameof(_OnButtonPressed));
  197. }
  198. }
  199. Run the scene and press the button. You should get the following result:
  200. .. image:: img/scripting_hello.png
  201. Why, hello there! Congratulations on scripting your first scene.
  202. **Note:** A common misunderstanding regarding this tutorial is how ``get_node(path)``
  203. works. For a given node, ``get_node(path)`` searches its immediate children.
  204. In the above code, this means that Button must be a child of Panel. If
  205. Button were instead a child of Label, the code to obtain it would be:
  206. .. tabs::
  207. .. code-tab:: gdscript GDScript
  208. # not for this case
  209. # but just in case
  210. get_node("Label/Button")
  211. .. code-tab:: csharp
  212. // not for this case
  213. // but just in case
  214. GetNode("Label/Button")
  215. Also, remember that nodes are referenced by name, not by type.