scripting.rst 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. .. _doc_scripting:
  2. Scripting
  3. =========
  4. Introduction
  5. ------------
  6. Before Godot 3.0, the only choice for scripting a game in Godot 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 of supporting languages more difficult.
  11. The "Main" languages in Godot, though, are GDScript and VisualScript. The
  12. main reason to choose them is the 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, though, go with C# and C++.
  15. GDScript
  16. ~~~~~~~~
  17. :ref:`doc_gdscript` is, as mentioned above, the main language used in Godot.
  18. Using it has some really positive points compared to other languages due
  19. to the high integration with Godot:
  20. * It's simple, elegant and designed to be friendly with 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 expanding as far as completing nodes, signals, and many other items pertaining to the current scene being edited.
  23. * Has vector types built-in (such as Vectors, transorms etc), making it efficient for heavy linear algebra.
  24. * It supports multiple threads as well as statically typed languages (which is one of the limitation that avoided us going for other VMs such as Lua, Squirrel, etc).
  25. * It uses no garbage collector, so it trades a small bit of automation (most objects are reference counted anyway), by determinism.
  26. * The dynamic nature of it makes it easy to optimize chunks of it in C++ (via GDNative) if more performance is required at some point, without recompiling the engine.
  27. If undecided, and have experience in programming (especially dynamically
  28. typed languages), go for GDScript!
  29. VisualScript
  30. ~~~~~~~~~~~~~
  31. Begining 3.0, Godot offers :ref:`visualscript<Visual Scripting>`. This is a
  32. somewhat typical implementation of blocks and connections language, but
  33. adapted to how Godot works.
  34. Visual scripting is a great tool for non-programmers, or even for developers
  35. with ample programming experience that want to make parts of the code more
  36. accessible to others (like game/level designers or artists).
  37. It can also be used by programmers to build state machines or custom
  38. visual node workflows (like a dialogue system).
  39. .NET / C#
  40. ~~~~~~~~~~~~
  41. As Microsoft's C# is a favorite amongst game developers, we have added
  42. solid and official support for it. C# is a very mature language with tons of code
  43. written for it. Support for this language was added thanks to a generous
  44. donation from Microsoft.
  45. It has an excellent tradeoff between performance and ease to use, although
  46. the main item one must be aware of is the garbage collector.
  47. For companies, this is usually the best choice, given the large amount of
  48. programmers that can be found in the labor market familiar with it, which
  49. reduces the learning time of the engine.
  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, this is one of our brightest additions for the 3.0 release.
  57. GDNative allows scripting in C++ without requiring 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 for an entire game (other parts can be written in GDScript or Visual
  64. Script). Yet, the API is very clear and easy to use as it resembles, mostly,
  65. Godot's actual C++ API.
  66. There are more languages available via the GDNative interface, but keep in mind
  67. we don't have official support for them so you will have to work with the
  68. provided in that case.
  69. Scripting a scene
  70. -----------------
  71. In the rest of this tutorial, we'll set up a simple GUI scene consisting of a
  72. button and a label, where pressing the button will update the label. This will
  73. demonstrate:
  74. - how to write a basic script and attach it to a node
  75. - how to hook up UI elements via *signals*
  76. - how to write a script that can access other nodes in the scene
  77. Before continuing, please make sure to read the :ref:`doc_gdscript` reference.
  78. It's a simple language and the reference is short, so it will not take more
  79. than a few minutes to get an overview of the concepts.
  80. Scene setup
  81. ~~~~~~~~~~~
  82. Use the add node dialog to create the following hierarchy, with the following
  83. nodes:
  84. - Panel
  85. * Label
  86. * Button
  87. It should look like this in the scene tree:
  88. .. image:: img/scripting_scene_tree.png
  89. Use the 2D editor to position and resize the button and label so that they
  90. look like the image below. You can set the text in the Inspector pane.
  91. .. image:: img/label_button_example.png
  92. Finally, save the scene, with a name such as "sayhello.tscn"
  93. .. _doc_scripting-adding_a_script:
  94. Adding a script
  95. ~~~~~~~~~~~~~~~
  96. Right click on the panel node, and then select "Attach Script" in the context
  97. menu:
  98. .. image:: img/add_script.png
  99. The script creation dialog will pop up. This dialog allows you to set the
  100. language, class name, and other relevant options.
  101. Actually, in GDScript, the file itself represents the class, so in this case,
  102. the class name field is not editable.
  103. The node we're attaching the script to is a panel, so the "Inherits" field
  104. should automatically be filled in with "Panel". This is what we want as our
  105. script's goal is to extend this panel node's functionality.
  106. Finally, enter a path name for the script and select "Create":
  107. .. image:: img/script_create.png
  108. Once this is done, the script will be created and added to the node. You can
  109. see this both as an extra icon in the node as well as in the script property:
  110. .. image:: img/script_added.png
  111. To edit the script, select either of the highlighted buttons. This will bring
  112. you to the script editor where an existing template will be included by default:
  113. .. image:: img/script_template.png
  114. There is not much in there. The "_ready()" function is called when the
  115. node (and all its children) enter the active scene. (Note: "_ready()" is not
  116. the a constructor; the constructor is "_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. etc.). 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 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, namely :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. In our case, because the button and the label are siblings under the panel
  144. where the script is attached, you can fetch the button as follows:
  145. .. tabs::
  146. .. code-tab:: gdscript GDScript
  147. get_node("Button")
  148. .. code-tab:: csharp
  149. GetNode("Button")
  150. Next, write a function which will be called when the button is pressed:
  151. .. tabs::
  152. .. code-tab:: gdscript GDScript
  153. func _on_button_pressed():
  154. get_node("Label").text="HELLO!"
  155. .. code-tab:: csharp
  156. public void _OnButtonPressed()
  157. {
  158. var label = (Label)GetNode("Label");
  159. label.Text = "HELLO!";
  160. }
  161. .. group-tab:: VS
  162. .. image:: img/signals.png
  163. Finally, connect the button's "pressed" signal to that callback in _ready(), by
  164. using :ref:`Object.connect() <class_Object_connect>`.
  165. .. tabs::
  166. .. code-tab:: gdscript GDScript
  167. func _ready():
  168. get_node("Button").connect("pressed",self,"_on_button_pressed")
  169. .. code-tab:: csharp
  170. public override void _Ready()
  171. {
  172. GetNode("Button").Connect("pressed", this, nameof(_OnButtonPressed));
  173. }
  174. The final script should look basically like this:
  175. .. tabs::
  176. .. code-tab:: gdscript GDScript
  177. extends Panel
  178. func _on_button_pressed():
  179. get_node("Label").text="HELLO!"
  180. func _ready():
  181. get_node("Button").connect("pressed",self,"_on_button_pressed")
  182. .. code-tab:: csharp
  183. using Godot;
  184. // IMPORTANT: the name of the class MUST match the filename exactly.
  185. // this is case sensitive!
  186. public class sayhello : Panel
  187. {
  188. public void _OnButtonPressed()
  189. {
  190. var label = (Label)GetNode("Label");
  191. label.Text = "HELLO!";
  192. }
  193. public override void _Ready()
  194. {
  195. GetNode("Button").Connect("pressed", this, nameof(_OnButtonPressed));
  196. }
  197. }
  198. Run the scene and press the button. You should get the following result:
  199. .. image:: img/scripting_hello.png
  200. Why hello there! Congratulations on scripting your first scene.
  201. **Note:** A common misunderstanding in this tutorial is how get_node(path)
  202. works. For some given node, get_node(path) searches its immediate children.
  203. In the above code, this means that *Button* must be a child of *Panel*. If
  204. *Button* were instead a child of *Label*, the code to obtain it would be:
  205. .. tabs::
  206. .. code-tab:: gdscript GDScript
  207. # not for this case
  208. # but just in case
  209. get_node("Label/Button")
  210. .. code-tab:: csharp
  211. // not for this case
  212. // but just in case
  213. GetNode("Label/Button")
  214. Also, remember that nodes are referenced by name, not by type.