scripting_first_script.rst 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. ..
  2. Intention:
  3. - Giving a *short* and sweet hands-on intro to GDScript. The page should
  4. focus on working in the code editor.
  5. - We assume the reader has programming foundations. If you don't, consider
  6. taking the course we recommend in the :ref:`introduction to Godot page <doc_learning_programming>`.
  7. Techniques:
  8. - Creating a sprite.
  9. - Creating a script.
  10. - _init() and _process().
  11. - Moving an object on screen.
  12. .. _doc_scripting_first_script:
  13. Creating your first script
  14. ==========================
  15. In this lesson, you will code your first script to make the Godot icon turn in
  16. circles using GDScript. As we mentioned :ref:`in the introduction
  17. <toc-learn-introduction>`, we assume you have programming foundations.
  18. The equivalent C# code has been included in another tab for convenience.
  19. .. image:: img/scripting_first_script_rotating_godot.gif
  20. .. seealso:: To learn more about GDScript, its keywords, and its syntax, head to
  21. the :ref:`GDScript reference<doc_gdscript>`.
  22. .. seealso:: To learn more about C#, head to the :ref:`C# basics <doc_c_sharp>` page.
  23. Project setup
  24. -------------
  25. Please :ref:`create a new project <doc_creating_and_importing_projects>` to
  26. start with a clean slate. Your project should contain one picture: the Godot
  27. icon, which we often use for prototyping in the community.
  28. .. Godot icon
  29. We need to create a Sprite2D node to display it in the game. In the Scene dock,
  30. click the Other Node button.
  31. .. image:: img/scripting_first_script_click_other_node.png
  32. Type "Sprite2D" in the search bar to filter nodes and double-click on Sprite2D
  33. to create the node.
  34. .. image:: img/scripting_first_script_add_sprite_node.png
  35. Your Scene tab should now only have a Sprite2D node.
  36. .. image:: img/scripting_first_script_scene_tree.png
  37. A Sprite2D node needs a texture to display. In the Inspector on the right, you
  38. can see that the Texture property says "[empty]". To display the Godot icon,
  39. click and drag the file ``icon.png`` from the FileSystem dock onto the Texture
  40. slot.
  41. .. image:: img/scripting_first_script_setting_texture.png
  42. .. note::
  43. You can create Sprite2D nodes automatically by dragging and dropping images
  44. on the viewport.
  45. .. image:: img/scripting_first_script_dragging_sprite.png
  46. Then, click and drag the icon in the viewport to center it in the game view.
  47. .. image:: img/scripting_first_script_centering_sprite.png
  48. Creating a new script
  49. ---------------------
  50. To create and attach a new script to our node, right-click on Sprite2D in the
  51. scene dock and select "Attach Script".
  52. .. image:: img/scripting_first_script_attach_script.png
  53. The Attach Node Script window appears. It allows you to select the script's
  54. language and file path, among other options.
  55. Change the Template from Default to Empty to start with a clean file. Leave the
  56. other options by default and click the Create button to create the script.
  57. .. image:: img/scripting_first_script_attach_node_script.png
  58. The Script workspace should appear with your new ``Sprite2D.gd`` file open and
  59. the following line of code:
  60. .. tabs::
  61. .. code-tab:: gdscript GDScript
  62. extends Sprite2D
  63. .. code-tab:: csharp C#
  64. public class Sprite : Godot.Sprite2D
  65. // Declare member variables here. Examples:
  66. // private int a = 2;
  67. // private string b = "text";
  68. // Called when the node enters the scene tree for the first time.
  69. public override void _Ready()
  70. {
  71. }
  72. // // Called every frame. 'delta' is the elapsed time since the previous frame.
  73. // public override void _Process(float delta)
  74. // {
  75. //
  76. // }
  77. Every GDScript file is implicitly a class. The ``extends`` keyword defines the
  78. class this script inherits or extends. In this case, it's ``Sprite2D``, meaning
  79. our script will get access to all the properties and functions of the Sprite2D
  80. node, including classes it extends, like ``Node2D``, ``CanvasItem``, and
  81. ``Node``.
  82. .. note:: In GDScript, if you omit the line with the ``extends`` keyword, your
  83. class will implicitly extend :ref:`Reference <class_Reference>`, which
  84. Godot uses to manage your application's memory.
  85. Inherited properties include the ones you can see in the Inspector dock, like
  86. our node's ``texture``.
  87. .. note::
  88. By default, the Inspector displays a node's properties in "Title Case", with
  89. capitalized words separated by a space. In GDScript code, these properties
  90. are in "snake_case", which is lowercase with words separated by an underscore.
  91. You can hover any property's name in the Inspector to see a description and
  92. its identifier in code.
  93. Hello, world!
  94. -------------
  95. Our script currently doesn't do anything. Let's make it print the text "Hello,
  96. world!" to the Output bottom panel to get started.
  97. Add the following code to your script:
  98. .. tabs::
  99. .. code-tab:: gdscript GDScript
  100. func _init():
  101. print("Hello, world!")
  102. .. code-tab:: csharp C#
  103. public Sprite()
  104. {
  105. GD.Print("Hello, world!");
  106. }
  107. Let's break it down. The ``func`` keyword defines a new function named
  108. ``_init``. This is a special name for our class's constructor. The engine calls
  109. ``_init()`` on every object or node upon creating it in memory, if you define
  110. this function.
  111. .. note:: GDScript is an indent-based language. The tab at the start of the line
  112. that says ``print()`` is necessary for the code to work. If you omit
  113. it or don't indent a line correctly, the editor will highlight it in
  114. red and display the following error message: "Indented block expected".
  115. Save the scene if you haven't already, then press :kbd:`F6` (:kbd:`Cmd + R` on macOS)
  116. to run it. Look at the **Output** bottom panel that expands.
  117. It should display "Hello, world!".
  118. .. image:: img/scripting_first_script_print_hello_world.png
  119. Delete the ``_init()`` function, so you're only left with the line ``extends
  120. Sprite2D``.
  121. Turning around
  122. --------------
  123. It's time to make our node move and rotate. To do so, we're going to add two
  124. member variables to our script: the movement speed in pixels per second and the
  125. angular speed in radians per second.
  126. .. tabs::
  127. .. code-tab:: gdscript GDScript
  128. var speed = 400
  129. var angular_speed = PI
  130. .. code-tab:: csharp C#
  131. private int Speed = 400;
  132. private float AngularSpeed = Mathf.Pi;
  133. Member variables sit near the top of the script, after any "extends" lines,
  134. but before functions. Every node
  135. instance with this script attached to it will have its own copy of the ``speed``
  136. and ``angular_speed`` properties.
  137. .. note:: Angles in Godot work in radians by default,
  138. but you have built-in functions and properties available if you prefer
  139. to calculate angles in degrees instead.
  140. To move our icon, we need to update its position and rotation every frame in the
  141. game loop. We can use the ``_process()`` virtual function of the ``Node`` class.
  142. If you define it in any class that extends the Node class, like Sprite2D, Godot
  143. will call the function every frame and pass it an argument named ``delta``, the
  144. time elapsed since the last frame.
  145. .. note::
  146. Games work by rendering many images per second, each called a frame, and
  147. they do so in a loop. We measure the rate at which a game produces images in
  148. Frames Per Second (FPS). Most games aim for 60 FPS, although you might find
  149. figures like 30 FPS on slower mobile devices or 90 to 240 for virtual
  150. reality games.
  151. The engine and game developers do their best to update the game world and
  152. render images at a constant time interval, but there are always small
  153. variations in frame render times. That's why the engine provides us with
  154. this delta time value, making our motion independent of our framerate.
  155. At the bottom of the script, define the function:
  156. .. tabs::
  157. .. code-tab:: gdscript GDScript
  158. func _process(delta):
  159. rotation += angular_speed * delta
  160. .. code-tab:: csharp C#
  161. public override void _Process(float delta)
  162. {
  163. Rotation += AngularSpeed * delta;
  164. }
  165. The ``func`` keyword defines a new function. After it, we have to write the
  166. function's name and arguments it takes in parentheses. A colon ends the
  167. definition, and the indented blocks that follow are the function's content or
  168. instructions.
  169. .. note:: Notice how ``_process()``, like ``_init()``, starts with a leading
  170. underscore. By convention, Godot's virtual functions, that is to say,
  171. built-in functions you can override to communicate with the engine,
  172. start with an underscore.
  173. The line inside the function, ``rotation += angular_speed * delta``, increments
  174. our sprite's rotation every frame. Here, ``rotation`` is a property inherited
  175. from the class ``Node2D``, which ``Sprite2D`` extends. It controls the rotation
  176. of our node and works with radians.
  177. .. tip:: In the code editor, you can ctrl-click on any built-in property or
  178. function like ``position``, ``rotation``, or ``_process`` to open the
  179. corresponding documentation in a new tab.
  180. Run the scene to see the Godot icon turn in-place.
  181. .. image:: img/scripting_first_script_godot_turning_in_place.gif
  182. Moving forward
  183. ~~~~~~~~~~~~~~
  184. Let's now make the node move. Add the following two lines to the ``_process()``
  185. function, ensuring the new lines are indented the same way as the one before
  186. them.
  187. .. tabs::
  188. .. code-tab:: gdscript GDScript
  189. var velocity = Vector2.UP.rotated(rotation) * speed
  190. position += velocity * delta
  191. .. code-tab:: csharp C#
  192. var velocity = Vector2.Up.Rotated(Rotation) * Speed;
  193. Position += velocity * delta;
  194. As we already saw, the ``var`` keyword defines a new variable. If you put it at
  195. the top of the script, it defines a property of the class. Inside a function, it
  196. defines a local variable: it only exists within the function's scope.
  197. We define a local variable named ``velocity``, a 2D vector representing both a
  198. direction and a speed. To make the node move forward, we start from the Vector2
  199. class's constant Vector2.UP, a vector pointing up, and rotate it by calling the
  200. ``Vector2.rotated()`` method. This expression, ``Vector2.UP.rotated(rotation)``,
  201. is a vector pointing forward relative to our icon. Multiplied by our ``speed``
  202. property, it gives us a velocity we can use to move the node forward.
  203. We add ``velocity * delta`` to the node's ``position`` to move it. The position
  204. itself is of type :ref:`Vector2 <class_Vector2>`, a built-in type in Godot
  205. representing a 2D vector.
  206. Run the scene to see the Godot head run in circles.
  207. .. image:: img/scripting_first_script_rotating_godot.gif
  208. .. note:: Moving a node like that does not take into account colliding with
  209. walls or the floor. In :ref:`doc_your_first_2d_game`, you will learn
  210. another approach to moving objects while detecting collisions.
  211. Our node currently moves by itself. In the next part
  212. :ref:`doc_scripting_player_input`, we'll use player input to control it.
  213. Complete script
  214. ---------------
  215. Here is the complete ``Sprite2D.gd`` file for reference.
  216. .. tabs::
  217. .. code-tab:: gdscript GDScript
  218. extends Sprite2D
  219. var speed = 400
  220. var angular_speed = PI
  221. func _process(delta):
  222. rotation += angular_speed * delta
  223. var velocity = Vector2.UP.rotated(rotation) * speed
  224. position += velocity * delta
  225. .. code-tab:: csharp C#
  226. using Godot;
  227. public class Sprite : Godot.Sprite2D
  228. {
  229. private int Speed = 400;
  230. private float AngularSpeed = Mathf.Pi;
  231. public override void _Process(float delta)
  232. {
  233. Rotation += AngularSpeed * delta;
  234. var velocity = Vector2.Up.Rotated(Rotation) * Speed;
  235. Position += velocity * delta;
  236. }
  237. }