Skip to content

Commit 80697b6

Browse files
committed
Add GDExtension C++ code snippets to scripting_first_script.rst
1 parent f8796c2 commit 80697b6

File tree

4 files changed

+176
-0
lines changed

4 files changed

+176
-0
lines changed

getting_started/step_by_step/scripting_first_script.rst

+98
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ The equivalent C# code has been included in another tab for convenience.
3030

3131
.. seealso:: To learn more about C#, head to the :ref:`C# basics <doc_c_sharp>` page.
3232

33+
.. seealso:: To learn more about GDExtension and godot-cpp, head to the :ref:`What is GDExtension? <doc_what_is_gdextension>` page.
34+
3335
Project setup
3436
-------------
3537

@@ -107,6 +109,35 @@ the following line of code:
107109
{
108110
}
109111

112+
.. code-tab:: cpp C++
113+
114+
#ifndef MY_SPRITE_2D_H
115+
#define MY_SPRITE_2D_H
116+
117+
#include <godot_cpp/classes/sprite2d.hpp>
118+
119+
using namespace godot;
120+
121+
namespace CustomNamespace {
122+
123+
// MySprite2D also needs to be bound in your GDExtension's register_types.cpp file.
124+
// More info on this in the GDExtension example setup tutorial.
125+
class MySprite2D : public Sprite2D {
126+
GDCLASS(MySprite2D, Sprite2D)
127+
128+
protected:
129+
// _bind_methods is required for all GDCLASS's or compilation will fail!
130+
static void _bind_methods() {}
131+
132+
public:
133+
// Default constructor with no parameters is required or compilation will fail!
134+
MySprite2D() {}
135+
};
136+
137+
} // CustomNamespace
138+
139+
#endif // MY_SPRITE_2D_H
140+
110141
Every GDScript file is implicitly a class. The ``extends`` keyword defines the
111142
class this script inherits or extends. In this case, it's ``Sprite2D``, meaning
112143
our script will get access to all the properties and functions of the Sprite2D
@@ -150,6 +181,17 @@ Add the following code to your script:
150181
GD.Print("Hello, world!");
151182
}
152183

184+
.. code-tab:: cpp C++
185+
186+
// Add this include at the top of your header file.
187+
#include <godot_cpp/variant/utility_functions.hpp>
188+
189+
// Add this inside your MySprite2D class.
190+
public:
191+
MySprite2D() {
192+
UtilityFunctions::print("Hello, world!");
193+
}
194+
153195

154196
Let's break it down. The ``func`` keyword defines a new function named
155197
``_init``. This is a special name for our class's constructor. The engine calls
@@ -188,6 +230,11 @@ angular speed in radians per second. Add the following after the ``extends Spri
188230
private int _speed = 400;
189231
private float _angularSpeed = Mathf.Pi;
190232

233+
.. code-tab:: cpp C++
234+
235+
int speed = 400;
236+
float angular_speed = Math_PI;
237+
191238
Member variables sit near the top of the script, after any "extends" lines,
192239
but before functions. Every node
193240
instance with this script attached to it will have its own copy of the ``speed``
@@ -231,6 +278,13 @@ At the bottom of the script, define the function:
231278
Rotation += _angularSpeed * (float)delta;
232279
}
233280

281+
.. code-tab:: cpp C++
282+
283+
void _process(double p_delta) override {
284+
// Note that properties (like rotation) are accessed via setters and getters in godot-cpp.
285+
set_rotation(get_rotation() + angular_speed * p_delta);
286+
}
287+
234288
The ``func`` keyword defines a new function. After it, we have to write the
235289
function's name and arguments it takes in parentheses. A colon ends the
236290
definition, and the indented blocks that follow are the function's content or
@@ -278,6 +332,14 @@ them.
278332

279333
Position += velocity * (float)delta;
280334

335+
.. code-tab:: cpp C++
336+
337+
// Note that the directional Vector2 constants do not exist in godot-cpp. So Vector2(0, -1) must be used.
338+
Vector2 velocity = Vector2(0, -1).rotated(get_rotation()) * speed;
339+
340+
set_position(get_position() + velocity * p_delta);
341+
342+
281343
As we already saw, the ``var`` keyword defines a new variable. If you put it at
282344
the top of the script, it defines a property of the class. Inside a function, it
283345
defines a local variable: it only exists within the function's scope.
@@ -343,3 +405,39 @@ Here is the complete ``sprite_2d.gd`` file for reference.
343405
Position += velocity * (float)delta;
344406
}
345407
}
408+
409+
.. code-tab:: cpp C++
410+
411+
#ifndef MY_SPRITE_2D_H
412+
#define MY_SPRITE_2D_H
413+
414+
#include <godot_cpp/classes/sprite2d.hpp>
415+
#include <godot_cpp/core/math.hpp>
416+
417+
using namespace godot;
418+
419+
namespace CustomNamespace {
420+
421+
class MySprite2D : public Sprite2D {
422+
GDCLASS(MySprite2D, Sprite2D)
423+
424+
int speed = 400;
425+
float angular_speed = Math_PI;
426+
427+
protected:
428+
static void _bind_methods() {}
429+
430+
public:
431+
MySprite2D() {}
432+
433+
void _process(double p_delta) override {
434+
set_rotation(get_rotation() + angular_speed * p_delta);
435+
436+
Vector2 velocity = Vector2(0, -1).rotated(get_rotation()) * speed;
437+
set_position(get_position() + velocity * p_delta);
438+
}
439+
};
440+
441+
} // CustomNamespace
442+
443+
#endif // MY_SPRITE_2D_H

getting_started/step_by_step/scripting_player_input.rst

+74
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,18 @@ code below.
5656

5757
Rotation += _angularSpeed * direction * (float)delta;
5858

59+
.. code-tab:: cpp C++
60+
61+
int direction = 0;
62+
if (Input::get_singleton()->is_action_pressed("ui_left")) {
63+
direction = -1;
64+
}
65+
if (Input::get_singleton()->is_action_pressed("ui_right")) {
66+
direction = 1;
67+
}
68+
69+
set_rotation(get_rotation() + angular_speed * direction * p_delta);
70+
5971
Our ``direction`` local variable is a multiplier representing the direction in
6072
which the player wants to turn. A value of ``0`` means the player isn't pressing
6173
the left or the right arrow key. A value of ``1`` means the player wants to turn
@@ -95,6 +107,12 @@ Comment out the lines ``var velocity = Vector2.UP.rotated(rotation) * speed`` an
95107

96108
//Position += velocity * (float)delta;
97109

110+
.. code-tab:: cpp C++
111+
112+
//Vector2 velocity = Vector2(0, -1).rotated(get_rotation()) * speed;
113+
114+
//set_position(get_position() + velocity * p_delta);
115+
98116
This will ignore the code that moved the icon's position in a circle without user input from the previous exercise.
99117

100118
If you run the scene with this code, the icon should rotate when you press
@@ -121,6 +139,13 @@ velocity. Uncomment the code and replace the line starting with ``var velocity``
121139
velocity = Vector2.Up.Rotated(Rotation) * _speed;
122140
}
123141

142+
.. code-tab:: cpp C++
143+
144+
Vector2 velocity = Vector2(0, 0);
145+
if (Input::get_singleton()->is_action_pressed("ui_up")) {
146+
velocity = Vector2(0, -1).rotated(get_rotation()) * speed;
147+
}
148+
124149
We initialize the ``velocity`` with a value of ``Vector2.ZERO``, another
125150
constant of the built-in ``Vector`` type representing a 2D vector of length 0.
126151

@@ -189,6 +214,55 @@ Here is the complete ``sprite_2d.gd`` file for reference.
189214
}
190215
}
191216

217+
.. code-tab:: cpp C++
218+
219+
#ifndef MY_SPRITE_2D_H
220+
#define MY_SPRITE_2D_H
221+
222+
#include <godot_cpp/classes/input.hpp>
223+
#include <godot_cpp/classes/sprite2d.hpp>
224+
#include <godot_cpp/core/math.hpp>
225+
226+
using namespace godot;
227+
228+
namespace CustomNamespace {
229+
230+
class MySprite2D : public Sprite2D {
231+
GDCLASS(MySprite2D, Sprite2D)
232+
233+
int speed = 400;
234+
float angular_speed = Math_PI;
235+
236+
protected:
237+
static void _bind_methods() {}
238+
239+
public:
240+
MySprite2D() {}
241+
242+
void _process(double p_delta) override {
243+
int direction = 0;
244+
if (Input::get_singleton()->is_action_pressed("ui_left")) {
245+
direction = -1;
246+
}
247+
if (Input::get_singleton()->is_action_pressed("ui_right")) {
248+
direction = 1;
249+
}
250+
251+
set_rotation(get_rotation() + angular_speed * p_delta);
252+
253+
Vector2 velocity = Vector2(0, 0);
254+
if (Input::get_singleton()->is_action_pressed("ui_up")) {
255+
velocity = Vector2(0, -1).rotated(get_rotation()) * speed;
256+
}
257+
258+
set_position(get_position() + velocity * p_delta);
259+
}
260+
};
261+
262+
} //namespace CustomNamespace
263+
264+
#endif // MY_SPRITE_2D_H
265+
192266
If you run the scene, you should now be able to rotate with the left and right
193267
arrow keys and move forward by pressing :kbd:`Up`.
194268

getting_started/step_by_step/signals.rst

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ what you can do with the Signal type directly.
3737
observer pattern. You can learn more about it in
3838
`Game Programming Patterns <https://gameprogrammingpatterns.com/observer.html>`__.
3939

40+
.. note:: Signals in godot-cpp are used in slightly different ways than GDScript or CSharp. To learn more head to the :ref:`GDExtension C++ example <doc_gdextension_cpp_signals_example>` page.
41+
4042
We will now use a signal to make our Godot icon from the previous lesson
4143
(:ref:`doc_scripting_player_input`) move and stop by pressing a button.
4244

tutorials/scripting/gdextension/gdextension_cpp_example.rst

+2
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,8 @@ The first two arguments are the minimum and maximum value and the third is the s
597597
There are a lot more options to choose from. These can be used to
598598
further configure how properties are displayed and set on the Godot side.
599599

600+
.. _doc_gdextension_cpp_signals_example:
601+
600602
Signals
601603
-------
602604

0 commit comments

Comments
 (0)