scripting.rst 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. Scripting
  2. =========
  3. Introduction
  4. ------------
  5. Much has been said about tools that allow users to create video games
  6. without programming. It's been a dream for many independent developers
  7. to create games without learning how to code. This need has been around
  8. for a long time, even inside companies, where game designers wish to
  9. have more control of the game flow.
  10. Many products have been shipped promising a no-programming environment,
  11. but the result is often incomplete, too complex or inefficient compared
  12. to traditional code. As a result, programming is here to stay for a long
  13. time. In fact, the general direction in game engines has been to add
  14. tools that try to reduce the amount of code that needs to be written for
  15. specific tasks, to speed up development.
  16. In that sense, Godot has taken some useful design decisions towards that
  17. goal. The first and most important is the scene system. The aim of it is
  18. not obvious at first, but works well later on. That is, to relieve
  19. programmers from the responsibility of architecting code.
  20. When designing games using the scene system, the whole project is
  21. fragmented in *complementary* scenes (not individual ones). Scenes
  22. complement each other, instead of being separate. There will be plenty
  23. of examples about this later on, but it's very important to remember it.
  24. For those with a good amount of programming expertise, this means a
  25. different design pattern to MVC. Godot promises efficiency at the
  26. expense of dropping the MVC habits, which are replaced by the *scenes as
  27. a complement* pattern.
  28. Godot also uses the `extend <http://c2.com/cgi/wiki?EmbedVsExtend>`__
  29. pattern for scripting, meaning that scripts extends from all the
  30. available engine classes.
  31. GDScript
  32. --------
  33. [[GDScript]] (click link for reference) is a dynamically typed scripting
  34. language to fit inside Godot. It was designed with the following goals:
  35. - First and most importantly, making it simple, familiar and as easy to
  36. learn as possible.
  37. - Making the code readable and error safe. The syntax is mostly
  38. borrowed from Python.
  39. Programmers generally take a few days to learn it, and within two weeks
  40. feel comfortable with it.
  41. As with most dynamically typed languages though, the higher productivity
  42. (code is easier to learn, faster to write, no compilation, etc) is
  43. balanced with a performance penalty, but most critical code is written
  44. in C++ already in the engine (vector ops, physics, math, indexing, etc),
  45. making the resulting performance more than enough for most types of
  46. games.
  47. In any case, if more performance is required, critical sections can be
  48. rewritten in C++ and exposed transparently to the script. This allows
  49. for replacing a GDScript class with a C++ class without altering the
  50. rest of the game.
  51. Scripting a Scene
  52. -----------------
  53. Before continuing, please make sure to read the [[GDScript]] reference.
  54. It's a simple language and the reference is short, should not take more
  55. than a few minutes to glance.
  56. Scene Setup
  57. ~~~~~~~~~~~
  58. This tutorial will begin by scripting a simple GUI scene. Use the add
  59. node dialog to create the following hierarchy, with the following nodes:
  60. - Panel
  61. \* Label
  62. \* Button
  63. It should look like this in the scene tree:
  64. .. image:: /img/scriptscene.png
  65. And try to make it look like this in the 2D editor, so it makes sense:
  66. .. image:: /img/scriptsceneimg.png
  67. Finally, save the scene, a fitting name could be "sayhello.scn"
  68. Adding a Script
  69. ~~~~~~~~~~~~~~~
  70. Select the Panel node, then press the "Add Script" Icon as follows:
  71. .. image:: /img/addscript.png
  72. | The script creation diallog will popup. This dialog allows to select
  73. the language, class name, etc.
  74. | GDScript does not use class names in script files, so that field is
  75. not editable.
  76. | The script should inherit from "Panel" (as it is meant to extend the
  77. node, which is of Panel type, this is automatically filled anyway).
  78. | Select the filename for the script (if you saved the scene previously,
  79. one will be automatically generated as sayhello.gd) and push
  80. `Create <>`__
  81. .. image:: /img/scriptcreate.png
  82. Once this is done, the script will be created and added to the node. You
  83. can see this both as an extra icon in the node, as well as in the script
  84. property:
  85. .. image:: /img/scriptadded.png
  86. To edit the script, pushing the icon above should do it (although, the
  87. UI will take you directly to the Script editor screen). So, here's the
  88. template script:
  89. .. image:: /img/script_template.png
  90. There is not much in there. The "\_ready()" function is called when the
  91. node (and all it's children) entered the active scene. (Remember, It's
  92. not a constructor, the constructor is "\_init()" ).
  93. The Role of the Script
  94. ~~~~~~~~~~~~~~~~~~~~~~
  95. A script basically adds a behavior to a node. It is used to control the
  96. node functions as well as other nodes (children, parent, siblings, etc).
  97. The local scope of the script is the node (just like in regular
  98. inheritance) and the virtual functions of the node are captured by the
  99. script.
  100. .. image:: /img/brainslug.jpg
  101. Handling a Signal
  102. ~~~~~~~~~~~~~~~~~
  103. Signals are used mostly in GUI nodes, (although other nodes have them
  104. too). Signals are "emitted" when some specific kind of action happens,
  105. and can be connected to any function of any script instance. In this
  106. step, the "pressed" signal from the button will be connected to a custom
  107. function.
  108. There is a GUI for connecting signals, just select the node and press
  109. the "Signals" button:
  110. .. image:: /img/signals.png
  111. Which will show the list of signals a Button can emit.
  112. .. image:: /img/button_connections.png
  113. | But this example will not use it. We don't want to make things *too*
  114. easy. So please close that screen!
  115. | In any case, at this point it is clear that that we are interested in
  116. the "pressed" signal, so instead of doing it with the visual
  117. interface, the connection will be done using code.
  118. For this, there is a function that is probably the one that Godot
  119. programmers will use the most, this is
  120. `get\_node() <https://github.com/okamstudio/godot/wiki/class_node#get_node>`__.
  121. This function uses paths to fetch nodes in the current tree or anywhere
  122. in the scene, relative to the node holding the script.
  123. To fetch the button, the following must be used:
  124. ::
  125. get_node("Button")
  126. So, next, a callback will be added for when a button is pressed, that
  127. will change the label's text:
  128. ::
  129. func _on_button_pressed():
  130. get_node("Label").set_text("HELLO!")
  131. Finally, the button "pressed" signal will be connected to that callback
  132. in \_ready(), by using
  133. `connect <https://github.com/okamstudio/godot/wiki/class_object#connect()>`__.
  134. ::
  135. func _ready():
  136. get_node("Button").connect("pressed",self,"_on_button_pressed")
  137. The final script should look like this:
  138. ::
  139. extends Panel
  140. # member variables here, example:
  141. # var a=2
  142. # var b="textvar"
  143. func _on_button_pressed():
  144. get_node("Label").set_text("HELLO!")
  145. func _ready():
  146. get_node("Button").connect("pressed",self,"_on_button_pressed")
  147. Running the scene should have the expected result when pressing the
  148. button:
  149. .. image:: /img/scripthello.png
  150. **Note:** As it is a common mistake in this tutorial, let's clarify
  151. again that get\_node(path) works by returning the immediate children to
  152. the node controlled by the script (in this case, *Panel*), so *Button*
  153. must be a child of *Panel* for the above code to work. To give this
  154. clarification more context, if *Button* was a child of *Label*, the code
  155. to obtain it would be:
  156. ::
  157. # not for this case
  158. # but just in case
  159. get_node("Label/Button")
  160. And, also, try to remember that nodes are referenced by name, not by
  161. type.
  162. *Juan Linietsky, Ariel Manzur, Distributed under the terms of the `CC
  163. By <https://creativecommons.org/licenses/by/3.0/legalcode>`__ license.*