mirror of
https://github.com/stan220/godot-docs.git
synced 2026-09-08 18:29:11 +00:00
Snake-case .tscn, .gd and _on_* callbacks
Co-authored-by: Doug Thompson <s-git@dougthompson.co.uk>
This commit is contained in:
co-authored by
Doug Thompson
parent
03081e0f14
commit
72c0af46b2
@@ -94,7 +94,7 @@ Add a script to the ``Mob`` like this:
|
|||||||
public:
|
public:
|
||||||
void _init() {}
|
void _init() {}
|
||||||
void _ready();
|
void _ready();
|
||||||
void _on_VisibleOnScreenNotifier2D_screen_exited();
|
void _on_visible_on_screen_notifier_2d_screen_exited();
|
||||||
|
|
||||||
static void _register_methods();
|
static void _register_methods();
|
||||||
};
|
};
|
||||||
@@ -164,7 +164,7 @@ add this code:
|
|||||||
.. code-tab:: cpp
|
.. code-tab:: cpp
|
||||||
|
|
||||||
// This code goes in `mob.cpp`.
|
// This code goes in `mob.cpp`.
|
||||||
void Mob::_on_VisibleOnScreenNotifier2D_screen_exited() {
|
void Mob::_on_visible_on_screen_notifier_2d_screen_exited() {
|
||||||
queue_free();
|
queue_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Create a new scene and add a :ref:`Node <class_Node>` named ``Main``.
|
|||||||
be a container for handling game logic. It does not require 2D functionality itself.)
|
be a container for handling game logic. It does not require 2D functionality itself.)
|
||||||
|
|
||||||
Click the **Instance** button (represented by a chain link icon) and select your saved
|
Click the **Instance** button (represented by a chain link icon) and select your saved
|
||||||
``Player.tscn``.
|
``player.tscn``.
|
||||||
|
|
||||||
.. image:: img/instance_scene.webp
|
.. image:: img/instance_scene.webp
|
||||||
|
|
||||||
@@ -178,9 +178,9 @@ under "Script Variables".
|
|||||||
|
|
||||||
You can assign this property's value in two ways:
|
You can assign this property's value in two ways:
|
||||||
|
|
||||||
- Drag ``Mob.tscn`` from the "FileSystem" dock and drop it in the **Mob Scene**
|
- Drag ``mob.tscn`` from the "FileSystem" dock and drop it in the **Mob Scene**
|
||||||
property.
|
property.
|
||||||
- Click the down arrow next to "[empty]" and choose "Load". Select ``Mob.tscn``.
|
- Click the down arrow next to "[empty]" and choose "Load". Select ``mob.tscn``.
|
||||||
|
|
||||||
Next, select the instance of the ``Player`` scene under ``Main`` node in the Scene dock,
|
Next, select the instance of the ``Player`` scene under ``Main`` node in the Scene dock,
|
||||||
and access the Node dock on the sidebar. Make sure to have the Signals tab selected
|
and access the Node dock on the sidebar. Make sure to have the Signals tab selected
|
||||||
@@ -424,11 +424,11 @@ call to ``_ready()``:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Let's also assign ``Main`` as our "Main Scene" - the one that runs automatically
|
Let's also assign ``Main`` as our "Main Scene" - the one that runs automatically
|
||||||
when the game launches. Press the "Play" button and select ``Main.tscn`` when
|
when the game launches. Press the "Play" button and select ``main.tscn`` when
|
||||||
prompted.
|
prompted.
|
||||||
|
|
||||||
.. tip:: If you had already set another scene as the "Main Scene", you can right
|
.. tip:: If you had already set another scene as the "Main Scene", you can right
|
||||||
click ``Main.tscn`` in the FileSystem dock and select "Set As Main Scene".
|
click ``main.tscn`` in the FileSystem dock and select "Set As Main Scene".
|
||||||
|
|
||||||
You should be able to move the player around, see mobs spawning, and see the
|
You should be able to move the player around, see mobs spawning, and see the
|
||||||
player disappear when hit by a mob.
|
player disappear when hit by a mob.
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ with the changing score:
|
|||||||
_hud->update_score(score);
|
_hud->update_score(score);
|
||||||
|
|
||||||
Now you're ready to play! Click the "Play the Project" button. You will be asked
|
Now you're ready to play! Click the "Play the Project" button. You will be asked
|
||||||
to select a main scene, so choose ``Main.tscn``.
|
to select a main scene, so choose ``main.tscn``.
|
||||||
|
|
||||||
Removing old creeps
|
Removing old creeps
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ a node to the scene, you can press :kbd:`Ctrl + a` (or :kbd:`Cmd + a` on macOS).
|
|||||||
|
|
||||||
.. image:: img/01.game_setup/05.main_node.png
|
.. image:: img/01.game_setup/05.main_node.png
|
||||||
|
|
||||||
Save the scene as ``Main.tscn`` by pressing :kbd:`Ctrl + s` (:kbd:`Cmd + s` on macOS).
|
Save the scene as ``main.tscn`` by pressing :kbd:`Ctrl + s` (:kbd:`Cmd + s` on macOS).
|
||||||
|
|
||||||
We'll start by adding a floor that'll prevent the characters from falling. To
|
We'll start by adding a floor that'll prevent the characters from falling. To
|
||||||
create static colliders like the floor, walls, or ceilings, you can use :ref:`StaticBody3D <class_StaticBody3D>` nodes. They require :ref:`CollisionShape3D <class_CollisionShape3D>` child nodes to
|
create static colliders like the floor, walls, or ceilings, you can use :ref:`StaticBody3D <class_StaticBody3D>` nodes. They require :ref:`CollisionShape3D <class_CollisionShape3D>` child nodes to
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ You can toggle the model's visibility by clicking the eye icon next to the
|
|||||||
|
|
||||||
|image5|
|
|image5|
|
||||||
|
|
||||||
Save the scene as ``Player.tscn``
|
Save the scene as ``player.tscn``
|
||||||
|
|
||||||
With the nodes ready, we can almost get coding. But first, we need to define
|
With the nodes ready, we can almost get coding. But first, we need to define
|
||||||
some input actions.
|
some input actions.
|
||||||
|
|||||||
@@ -359,14 +359,14 @@ tab at the top of the editor to do so.
|
|||||||
|image1|
|
|image1|
|
||||||
|
|
||||||
If you closed the scene before, head to the *FileSystem* dock and double-click
|
If you closed the scene before, head to the *FileSystem* dock and double-click
|
||||||
``Main.tscn`` to re-open it.
|
``main.tscn`` to re-open it.
|
||||||
|
|
||||||
To instantiate the ``Player``, right-click on the ``Main`` node and select *Instance
|
To instantiate the ``Player``, right-click on the ``Main`` node and select *Instance
|
||||||
Child Scene*.
|
Child Scene*.
|
||||||
|
|
||||||
|image2|
|
|image2|
|
||||||
|
|
||||||
In the popup, double-click ``Player.tscn``. The character should appear in the
|
In the popup, double-click ``player.tscn``. The character should appear in the
|
||||||
center of the viewport.
|
center of the viewport.
|
||||||
|
|
||||||
Adding a camera
|
Adding a camera
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ In this part, you're going to code the monsters, which we'll call mobs. In the
|
|||||||
next lesson, we'll spawn them randomly around the playable area.
|
next lesson, we'll spawn them randomly around the playable area.
|
||||||
|
|
||||||
Let's design the monsters themselves in a new scene. The node structure is going
|
Let's design the monsters themselves in a new scene. The node structure is going
|
||||||
to be similar to the ``Player.tscn`` scene.
|
to be similar to the ``player.tscn`` scene.
|
||||||
|
|
||||||
Create a scene with, once again, a :ref:`CharacterBody3D <class_CharacterBody3D>` node as its root. Name it
|
Create a scene with, once again, a :ref:`CharacterBody3D <class_CharacterBody3D>` node as its root. Name it
|
||||||
``Mob``. Add a child node :ref:`Node3D <class_Node3D>`, name it ``Pivot``. And drag and drop
|
``Mob``. Add a child node :ref:`Node3D <class_Node3D>`, name it ``Pivot``. And drag and drop
|
||||||
@@ -93,7 +93,7 @@ Coding the mob's movement
|
|||||||
|
|
||||||
Let's implement the monster's motion. We're going to do this in two steps.
|
Let's implement the monster's motion. We're going to do this in two steps.
|
||||||
First, we'll write a script on the ``Mob`` that defines a function to initialize
|
First, we'll write a script on the ``Mob`` that defines a function to initialize
|
||||||
the monster. We'll then code the randomized spawn mechanism in the ``Main.tscn`` scene
|
the monster. We'll then code the randomized spawn mechanism in the ``main.tscn`` scene
|
||||||
and call the function from there.
|
and call the function from there.
|
||||||
|
|
||||||
Attach a script to the ``Mob``.
|
Attach a script to the ``Mob``.
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ you will have monsters roaming the game board.
|
|||||||
|
|
||||||
|image0|
|
|image0|
|
||||||
|
|
||||||
Double-click on ``Main.tscn`` in the *FileSystem* dock to open the ``Main`` scene.
|
Double-click on ``main.tscn`` in the *FileSystem* dock to open the ``Main`` scene.
|
||||||
|
|
||||||
Before drawing the path, we're going to change the game resolution. Our game has
|
Before drawing the path, we're going to change the game resolution. Our game has
|
||||||
a default window size of ``1152x648``. We're going to set it to ``720x540``, a
|
a default window size of ``1152x648``. We're going to set it to ``720x540``, a
|
||||||
@@ -157,7 +157,7 @@ Spawning monsters randomly
|
|||||||
|
|
||||||
Right-click on the ``Main`` node and attach a new script to it.
|
Right-click on the ``Main`` node and attach a new script to it.
|
||||||
|
|
||||||
We first export a variable to the *Inspector* so that we can assign ``Mob.tscn``
|
We first export a variable to the *Inspector* so that we can assign ``mob.tscn``
|
||||||
or any other monster to it.
|
or any other monster to it.
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
@@ -181,9 +181,9 @@ or any other monster to it.
|
|||||||
|
|
||||||
We want to spawn mobs at regular time intervals. To do this, we need to go back
|
We want to spawn mobs at regular time intervals. To do this, we need to go back
|
||||||
to the scene and add a timer. Before that, though, we need to assign the
|
to the scene and add a timer. Before that, though, we need to assign the
|
||||||
``Mob.tscn`` file to the ``mob_scene`` property above (otherwise it's null!)
|
``mob.tscn`` file to the ``mob_scene`` property above (otherwise it's null!)
|
||||||
|
|
||||||
Head back to the 3D screen and select the ``Main`` node. Drag ``Mob.tscn`` from
|
Head back to the 3D screen and select the ``Main`` node. Drag ``mob.tscn`` from
|
||||||
the *FileSystem* dock to the *Mob Scene* slot in the *Inspector*.
|
the *FileSystem* dock to the *Mob Scene* slot in the *Inspector*.
|
||||||
|
|
||||||
|image20|
|
|image20|
|
||||||
@@ -269,7 +269,7 @@ what the *PathFollow* node's ``progress_ratio`` expects:
|
|||||||
The path we have set is around the camera's viewport, so any random value between 0 and 1
|
The path we have set is around the camera's viewport, so any random value between 0 and 1
|
||||||
is a random position alongside the edges of the viewport!
|
is a random position alongside the edges of the viewport!
|
||||||
|
|
||||||
Here is the complete ``Main.gd`` script so far, for reference.
|
Here is the complete ``main.gd`` script so far, for reference.
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ see a list of named checkboxes.
|
|||||||
|
|
||||||
|image4|
|
|image4|
|
||||||
|
|
||||||
Next up are the ``Player`` and the ``Mob``. Open ``Player.tscn`` by double-clicking
|
Next up are the ``Player`` and the ``Mob``. Open ``player.tscn`` by double-clicking
|
||||||
the file in the *FileSystem* dock.
|
the file in the *FileSystem* dock.
|
||||||
|
|
||||||
Select the *Player* node and set its *Collision -> Mask* to both "enemies" and
|
Select the *Player* node and set its *Collision -> Mask* to both "enemies" and
|
||||||
@@ -83,7 +83,7 @@ Select the *Player* node and set its *Collision -> Mask* to both "enemies" and
|
|||||||
|
|
||||||
|image5|
|
|image5|
|
||||||
|
|
||||||
Then, open the *Mob* scene by double-clicking on ``Mob.tscn`` and select the
|
Then, open the *Mob* scene by double-clicking on ``mob.tscn`` and select the
|
||||||
``Mob`` node.
|
``Mob`` node.
|
||||||
|
|
||||||
Set its *Collision -> Layer* to "enemies" and unset its *Collision -> Mask*,
|
Set its *Collision -> Layer* to "enemies" and unset its *Collision -> Mask*,
|
||||||
@@ -180,7 +180,7 @@ We need to detect collisions with a monster and to differentiate them from
|
|||||||
collisions with the floor. To do so, we can use Godot's :ref:`group
|
collisions with the floor. To do so, we can use Godot's :ref:`group
|
||||||
<doc_groups>` tagging feature.
|
<doc_groups>` tagging feature.
|
||||||
|
|
||||||
Open the scene ``Mob.tscn`` again and select the *Mob* node. Go to the *Node*
|
Open the scene ``mob.tscn`` again and select the *Mob* node. Go to the *Node*
|
||||||
dock on the right to see a list of signals. The *Node* dock has two tabs:
|
dock on the right to see a list of signals. The *Node* dock has two tabs:
|
||||||
*Signals*, which you've already used, and *Groups*, which allows you to assign
|
*Signals*, which you've already used, and *Groups*, which allows you to assign
|
||||||
tags to nodes.
|
tags to nodes.
|
||||||
@@ -347,7 +347,7 @@ destroy the mob.
|
|||||||
We will use the signal to add points to the score in the next lesson.
|
We will use the signal to add points to the score in the next lesson.
|
||||||
|
|
||||||
With that, you should be able to kill monsters by jumping on them. You can press
|
With that, you should be able to kill monsters by jumping on them. You can press
|
||||||
:kbd:`F5` to try the game and set ``Main.tscn`` as your project's main scene.
|
:kbd:`F5` to try the game and set ``main.tscn`` as your project's main scene.
|
||||||
|
|
||||||
However, the player won't die yet. We'll work on that in the next part.
|
However, the player won't die yet. We'll work on that in the next part.
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ works well for hitboxes.
|
|||||||
Hitbox with the Area node
|
Hitbox with the Area node
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Head back to the ``Player.tscn`` scene and add a new child node :ref:`Area3D <class_Area3D>`. Name it
|
Head back to the ``player.tscn`` scene and add a new child node :ref:`Area3D <class_Area3D>`. Name it
|
||||||
``MobDetector``
|
``MobDetector``
|
||||||
Add a :ref:`CollisionShape3D <class_CollisionShape3D>` node as a child of it.
|
Add a :ref:`CollisionShape3D <class_CollisionShape3D>` node as a child of it.
|
||||||
|
|
||||||
@@ -128,7 +128,7 @@ We can use the ``Player``\ 's ``hit`` signal to end the game. All we need
|
|||||||
to do is connect it to the ``Main`` node and stop the ``MobTimer`` in
|
to do is connect it to the ``Main`` node and stop the ``MobTimer`` in
|
||||||
reaction.
|
reaction.
|
||||||
|
|
||||||
Open ``Main.tscn``, select the ``Player`` node, and in the *Node* dock,
|
Open ``main.tscn``, select the ``Player`` node, and in the *Node* dock,
|
||||||
connect its ``hit`` signal to the ``Main`` node.
|
connect its ``hit`` signal to the ``Main`` node.
|
||||||
|
|
||||||
|image5|
|
|image5|
|
||||||
@@ -165,7 +165,7 @@ Code checkpoint
|
|||||||
Here are the complete scripts for the ``Main``, ``Mob``, and ``Player`` nodes,
|
Here are the complete scripts for the ``Main``, ``Mob``, and ``Player`` nodes,
|
||||||
for reference. You can use them to compare and check your code.
|
for reference. You can use them to compare and check your code.
|
||||||
|
|
||||||
Starting with ``Main.gd``.
|
Starting with ``main.gd``.
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|||||||
@@ -102,12 +102,12 @@ monsters from the code, we cannot connect the mob signal to the ``ScoreLabel`` v
|
|||||||
Instead, we have to make the connection from the code every time we spawn a
|
Instead, we have to make the connection from the code every time we spawn a
|
||||||
monster.
|
monster.
|
||||||
|
|
||||||
Open the script ``Main.gd``. If it's still open, you can click on its name in
|
Open the script ``main.gd``. If it's still open, you can click on its name in
|
||||||
the script editor's left column.
|
the script editor's left column.
|
||||||
|
|
||||||
|image8|
|
|image8|
|
||||||
|
|
||||||
Alternatively, you can double-click the ``Main.gd`` file in the *FileSystem*
|
Alternatively, you can double-click the ``main.gd`` file in the *FileSystem*
|
||||||
dock.
|
dock.
|
||||||
|
|
||||||
At the bottom of the ``_on_mob_timer_timeout()`` function, add the following
|
At the bottom of the ``_on_mob_timer_timeout()`` function, add the following
|
||||||
@@ -119,7 +119,7 @@ line:
|
|||||||
func _on_mob_timer_timeout():
|
func _on_mob_timer_timeout():
|
||||||
#...
|
#...
|
||||||
# We connect the mob to the score label to update the score upon squashing one.
|
# We connect the mob to the score label to update the score upon squashing one.
|
||||||
mob.squashed.connect($UserInterface/ScoreLabel._on_Mob_squashed.bind())
|
mob.squashed.connect($UserInterface/ScoreLabel._on_mob_squashed.bind())
|
||||||
|
|
||||||
.. code-tab:: csharp
|
.. code-tab:: csharp
|
||||||
|
|
||||||
@@ -131,9 +131,9 @@ line:
|
|||||||
}
|
}
|
||||||
|
|
||||||
This line means that when the mob emits the ``squashed`` signal, the
|
This line means that when the mob emits the ``squashed`` signal, the
|
||||||
``ScoreLabel`` node will receive it and call the function ``_on_Mob_squashed()``.
|
``ScoreLabel`` node will receive it and call the function ``_on_mob_squashed()``.
|
||||||
|
|
||||||
Head back to the ``ScoreLabel.gd`` script to define the ``_on_Mob_squashed()``
|
Head back to the ``ScoreLabel.gd`` script to define the ``_on_mob_squashed()``
|
||||||
callback function.
|
callback function.
|
||||||
|
|
||||||
There, we increment the score and update the displayed text.
|
There, we increment the score and update the displayed text.
|
||||||
@@ -141,7 +141,7 @@ There, we increment the score and update the displayed text.
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
func _on_Mob_squashed():
|
func _on_mob_squashed():
|
||||||
score += 1
|
score += 1
|
||||||
text = "Score: %s" % score
|
text = "Score: %s" % score
|
||||||
|
|
||||||
@@ -163,12 +163,6 @@ when using the ``print()`` function.
|
|||||||
You can learn more about string formatting here: :ref:`doc_gdscript_printf`.
|
You can learn more about string formatting here: :ref:`doc_gdscript_printf`.
|
||||||
In C#, consider using `string interpolation with "$" <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated>`_.
|
In C#, consider using `string interpolation with "$" <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated>`_.
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
If you get an error when you squash a mob
|
|
||||||
check your capital letters in the signal "_on_Mob_squashed"
|
|
||||||
|
|
||||||
You can now play the game and squash a few enemies to see the score
|
You can now play the game and squash a few enemies to see the score
|
||||||
increase.
|
increase.
|
||||||
|
|
||||||
@@ -188,7 +182,7 @@ Retrying the game
|
|||||||
We'll now add the ability to play again after dying. When the player dies, we'll
|
We'll now add the ability to play again after dying. When the player dies, we'll
|
||||||
display a message on the screen and wait for input.
|
display a message on the screen and wait for input.
|
||||||
|
|
||||||
Head back to the ``Main.tscn`` scene, select the ``UserInterface`` node, add a
|
Head back to the ``main.tscn`` scene, select the ``UserInterface`` node, add a
|
||||||
child node :ref:`ColorRect <class_ColorRect>`, and name it ``Retry``. This node fills a
|
child node :ref:`ColorRect <class_ColorRect>`, and name it ``Retry``. This node fills a
|
||||||
rectangle with a uniform color and will serve as an overlay to darken the
|
rectangle with a uniform color and will serve as an overlay to darken the
|
||||||
screen.
|
screen.
|
||||||
@@ -234,7 +228,7 @@ Coding the retry option
|
|||||||
We can now head to the code to show and hide the ``Retry`` node when the player
|
We can now head to the code to show and hide the ``Retry`` node when the player
|
||||||
dies and plays again.
|
dies and plays again.
|
||||||
|
|
||||||
Open the script ``Main.gd``. First, we want to hide the overlay at the start of
|
Open the script ``main.gd``. First, we want to hide the overlay at the start of
|
||||||
the game. Add this line to the ``_ready()`` function.
|
the game. Add this line to the ``_ready()`` function.
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
@@ -361,7 +355,7 @@ game's viewport.
|
|||||||
And that does it for this lesson. In the next part, we'll add an animation to
|
And that does it for this lesson. In the next part, we'll add an animation to
|
||||||
make the game both look and feel much nicer.
|
make the game both look and feel much nicer.
|
||||||
|
|
||||||
Here is the complete ``Main.gd`` script for reference.
|
Here is the complete ``main.gd`` script for reference.
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
@@ -391,7 +385,7 @@ Here is the complete ``Main.gd`` script for reference.
|
|||||||
add_child(mob)
|
add_child(mob)
|
||||||
|
|
||||||
# We connect the mob to the score label to update the score upon squashing one.
|
# We connect the mob to the score label to update the score upon squashing one.
|
||||||
mob.squashed.connect($UserInterface/ScoreLabel._on_Mob_squashed.bind())
|
mob.squashed.connect($UserInterface/ScoreLabel._on_mob_squashed.bind())
|
||||||
|
|
||||||
func _on_player_hit():
|
func _on_player_hit():
|
||||||
$MobTimer.stop()
|
$MobTimer.stop()
|
||||||
|
|||||||
@@ -259,11 +259,11 @@ node structure, you can copy them to different scenes.
|
|||||||
For example, both the ``Mob`` and the ``Player`` scenes have a ``Pivot`` and a
|
For example, both the ``Mob`` and the ``Player`` scenes have a ``Pivot`` and a
|
||||||
``Character`` node, so we can reuse animations between them.
|
``Character`` node, so we can reuse animations between them.
|
||||||
|
|
||||||
Open the *Player* scene, select the AnimationPlayer node and open the "float"
|
Open the *Player* scene, select the AnimationPlayer node and open the "float"
|
||||||
animation. Next, click on **Animation > Copy**. Then open ``Mob.tscn``,
|
animation. Next, click on **Animation > Copy**. Then open ``mob.tscn``,
|
||||||
create an AnimationPlayer child node and select it. Click **Animation > Paste**
|
create an AnimationPlayer child node and select it. Click **Animation > Paste**
|
||||||
and make sure that the button with an "A+" icon (Autoplay on Load) and the
|
and make sure that the button with an "A+" icon (Autoplay on Load) and the
|
||||||
looping arrows (Animation looping) are also turned on in the animation editor
|
looping arrows (Animation looping) are also turned on in the animation editor
|
||||||
in the bottom panel. That's it; all monsters will now play the float animation.
|
in the bottom panel. That's it; all monsters will now play the float animation.
|
||||||
|
|
||||||
We can change the playback speed based on the creature's ``random_speed``. Open
|
We can change the playback speed based on the creature's ``random_speed``. Open
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ into any number of scenes. This feature helps you break down and organize your
|
|||||||
game's different components.
|
game's different components.
|
||||||
|
|
||||||
You can create as many scenes as you'd like and save them as files with the
|
You can create as many scenes as you'd like and save them as files with the
|
||||||
``.tscn`` extension, which stands for "text scene". The ``Label.tscn`` file from
|
``.tscn`` extension, which stands for "text scene". The ``tabel.tscn`` file from
|
||||||
the previous lesson was an example. We call those files "Packed Scenes" as they
|
the previous lesson was an example. We call those files "Packed Scenes" as they
|
||||||
pack information about your scene's content.
|
pack information about your scene's content.
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ editor hides their content by default. When you instance the Ball, you only see
|
|||||||
the Ball node. Notice also how each duplicate has a unique name.
|
the Ball node. Notice also how each duplicate has a unique name.
|
||||||
|
|
||||||
Every instance of the Ball scene starts with the same structure and properties
|
Every instance of the Ball scene starts with the same structure and properties
|
||||||
as ``Ball.tscn``. However, you can modify each independently, such as changing
|
as ``ball.tscn``. However, you can modify each independently, such as changing
|
||||||
how they bounce, how heavy they are, or any property exposed by the source
|
how they bounce, how heavy they are, or any property exposed by the source
|
||||||
scene.
|
scene.
|
||||||
|
|
||||||
@@ -64,8 +64,8 @@ Finally, click the Import & Edit button.
|
|||||||
|
|
||||||
.. image:: img/instancing_import_and_edit_button.png
|
.. image:: img/instancing_import_and_edit_button.png
|
||||||
|
|
||||||
The project contains two packed scenes: ``Main.tscn``, containing walls against
|
The project contains two packed scenes: ``main.tscn``, containing walls against
|
||||||
which the ball collides, and ``Ball.tscn``. The Main scene should open
|
which the ball collides, and ``ball.tscn``. The Main scene should open
|
||||||
automatically.
|
automatically.
|
||||||
|
|
||||||
.. image:: img/instancing_main_scene.png
|
.. image:: img/instancing_main_scene.png
|
||||||
@@ -111,14 +111,14 @@ There is more to instances. With this feature, you can:
|
|||||||
|
|
||||||
1. Change the properties of one ball without affecting the others using the
|
1. Change the properties of one ball without affecting the others using the
|
||||||
Inspector.
|
Inspector.
|
||||||
2. Change the default properties of every Ball by opening the ``Ball.tscn`` scene
|
2. Change the default properties of every Ball by opening the ``ball.tscn`` scene
|
||||||
and making a change to the Ball node there. Upon saving, all instances of the
|
and making a change to the Ball node there. Upon saving, all instances of the
|
||||||
Ball in the project will see their values update.
|
Ball in the project will see their values update.
|
||||||
|
|
||||||
.. note:: Changing a property on an instance always overrides values from the
|
.. note:: Changing a property on an instance always overrides values from the
|
||||||
corresponding packed scene.
|
corresponding packed scene.
|
||||||
|
|
||||||
Let's try this. Open ``Ball.tscn`` and select the Ball node. In the Inspector on
|
Let's try this. Open ``ball.tscn`` and select the Ball node. In the Inspector on
|
||||||
the right, click on the PhysicsMaterial property to expand it.
|
the right, click on the PhysicsMaterial property to expand it.
|
||||||
|
|
||||||
.. image:: img/instancing_physics_material_expand.png
|
.. image:: img/instancing_physics_material_expand.png
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ A popup window appears and invites you to select the main scene.
|
|||||||
.. image:: img/nodes_and_scenes_13_main_scene_popup.webp
|
.. image:: img/nodes_and_scenes_13_main_scene_popup.webp
|
||||||
|
|
||||||
Click the Select button, and in the file dialog that appears, double click on
|
Click the Select button, and in the file dialog that appears, double click on
|
||||||
label.tscn.
|
``label.tscn``.
|
||||||
|
|
||||||
.. image:: img/nodes_and_scenes_14_select_main_scene.webp
|
.. image:: img/nodes_and_scenes_14_select_main_scene.webp
|
||||||
|
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ other options by default and click the Create button to create the script.
|
|||||||
|
|
||||||
.. image:: img/scripting_first_script_attach_node_script.webp
|
.. image:: img/scripting_first_script_attach_node_script.webp
|
||||||
|
|
||||||
The Script workspace should appear with your new ``Sprite2D.gd`` file open and
|
The Script workspace should appear with your new ``sprite_2d.gd`` file open and
|
||||||
the following line of code:
|
the following line of code:
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
@@ -305,7 +305,7 @@ Our node currently moves by itself. In the next part
|
|||||||
Complete script
|
Complete script
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Here is the complete ``Sprite2D.gd`` file for reference.
|
Here is the complete ``sprite_2d.gd`` file for reference.
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Listening to player input
|
|||||||
|
|
||||||
Building upon the previous lesson :ref:`doc_scripting_first_script`, let's look
|
Building upon the previous lesson :ref:`doc_scripting_first_script`, let's look
|
||||||
at another important feature of any game: giving control to the player.
|
at another important feature of any game: giving control to the player.
|
||||||
To add this, we need to modify our ``Sprite2D.gd`` code.
|
To add this, we need to modify our ``sprite_2d.gd`` code.
|
||||||
|
|
||||||
.. image:: img/scripting_first_script_moving_with_input.gif
|
.. image:: img/scripting_first_script_moving_with_input.gif
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ causing the sprite to move forward.
|
|||||||
Complete script
|
Complete script
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Here is the complete ``Sprite2D.gd`` file for reference.
|
Here is the complete ``sprite_2d.gd`` file for reference.
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ following code, which we saw two lessons ago:
|
|||||||
Position += velocity * (float)delta;
|
Position += velocity * (float)delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
Your complete ``Sprite2D.gd`` code should look like the following.
|
Your complete ``sprite_2d.gd`` code should look like the following.
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
@@ -313,7 +313,7 @@ which the script is attached. When the Timer emits ``timeout``, we want to call
|
|||||||
the function ``_on_timer_timeout()``, that we need to define. Let's add it at the
|
the function ``_on_timer_timeout()``, that we need to define. Let's add it at the
|
||||||
bottom of our script and use it to toggle our sprite's visibility.
|
bottom of our script and use it to toggle our sprite's visibility.
|
||||||
|
|
||||||
.. note:: By convention, we name these callback methods in GDScript as
|
.. note:: By convention, we name these callback methods in GDScript as
|
||||||
"_on_node_name_signal_name" and in C# as "OnNodeNameSignalName".
|
"_on_node_name_signal_name" and in C# as "OnNodeNameSignalName".
|
||||||
Here, it'll be "_on_timer_timeout" for GDScript and OnTimerTimeout() for C#.
|
Here, it'll be "_on_timer_timeout" for GDScript and OnTimerTimeout() for C#.
|
||||||
|
|
||||||
@@ -341,7 +341,7 @@ Complete script
|
|||||||
---------------
|
---------------
|
||||||
|
|
||||||
That's it for our little moving and blinking Godot icon demo!
|
That's it for our little moving and blinking Godot icon demo!
|
||||||
Here is the complete ``Sprite2D.gd`` file for reference.
|
Here is the complete ``sprite_2d.gd`` file for reference.
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
@@ -354,7 +354,7 @@ Here is the complete ``Sprite2D.gd`` file for reference.
|
|||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var timer = get_node("Timer")
|
var timer = get_node("Timer")
|
||||||
timer.timeout.connect(_on_Timer_timeout)
|
timer.timeout.connect(_on_timer_timeout)
|
||||||
|
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
@@ -367,7 +367,7 @@ Here is the complete ``Sprite2D.gd`` file for reference.
|
|||||||
set_process(not is_processing())
|
set_process(not is_processing())
|
||||||
|
|
||||||
|
|
||||||
func _on_Timer_timeout():
|
func _on_timer_timeout():
|
||||||
visible = not visible
|
visible = not visible
|
||||||
|
|
||||||
.. code-tab:: csharp C#
|
.. code-tab:: csharp C#
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ Creating a MeshLibrary
|
|||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
To begin, you need a :ref:`class_MeshLibrary`, which is a collection
|
To begin, you need a :ref:`class_MeshLibrary`, which is a collection
|
||||||
of individual meshes that can be used in the gridmap. Open the "MeshLibrary_Source.tscn"
|
of individual meshes that can be used in the gridmap. Open the "mesh_library_source.tscn"
|
||||||
scene to see an example of how to set up the mesh library.
|
scene to see an example of how to set up the mesh library.
|
||||||
|
|
||||||
.. image:: img/gridmap_meshlibrary1.png
|
.. image:: img/gridmap_meshlibrary1.png
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ and :ref:`set_recording_active() <class_AudioEffectRecord_method_set_recording_a
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
func _on_RecordButton_pressed():
|
func _on_record_button_pressed():
|
||||||
if effect.is_recording_active():
|
if effect.is_recording_active():
|
||||||
recording = effect.get_recording()
|
recording = effect.get_recording()
|
||||||
$PlayButton.disabled = false
|
$PlayButton.disabled = false
|
||||||
@@ -114,7 +114,7 @@ the recorded stream can be stored into the ``recording`` variable by calling
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
func _on_PlayButton_pressed():
|
func _on_play_button_pressed():
|
||||||
print(recording)
|
print(recording)
|
||||||
print(recording.format)
|
print(recording.format)
|
||||||
print(recording.mix_rate)
|
print(recording.mix_rate)
|
||||||
@@ -145,7 +145,7 @@ To playback the recording, you assign the recording as the stream of the
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
func _on_SaveButton_pressed():
|
func _on_save_button_pressed():
|
||||||
var save_path = $SaveButton/Filename.text
|
var save_path = $SaveButton/Filename.text
|
||||||
recording.save_to_wav(save_path)
|
recording.save_to_wav(save_path)
|
||||||
$Status.text = "Saved WAV file to: %s\n(%s)" % [save_path, ProjectSettings.globalize_path(save_path)]
|
$Status.text = "Saved WAV file to: %s\n(%s)" % [save_path, ProjectSettings.globalize_path(save_path)]
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ declarative code.
|
|||||||
|
|
||||||
Each system's capabilities are different as a result.
|
Each system's capabilities are different as a result.
|
||||||
Scenes can define how an extended class initializes, but not what its
|
Scenes can define how an extended class initializes, but not what its
|
||||||
behavior actually is. Scenes are often used in conjunction with a script,
|
behavior actually is. Scenes are often used in conjunction with a script,
|
||||||
the scene declaring a composition of nodes, and the script adding behaviour with imperative code.
|
the scene declaring a composition of nodes, and the script adding behaviour with imperative code.
|
||||||
|
|
||||||
Anonymous types
|
Anonymous types
|
||||||
@@ -150,13 +150,13 @@ with it, and finally adds it as a child of the ``Main`` node:
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
# Main.gd
|
# main.gd
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
func _init():
|
func _init():
|
||||||
var child = Node.new()
|
var child = Node.new()
|
||||||
child.name = "Child"
|
child.name = "Child"
|
||||||
child.script = preload("Child.gd")
|
child.script = preload("child.gd")
|
||||||
child.owner = self
|
child.owner = self
|
||||||
add_child(child)
|
add_child(child)
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ In the end, the best approach is to consider the following:
|
|||||||
{
|
{
|
||||||
public static PackedScene MyScene { get; } = GD.Load<PackedScene>("MyScene.tscn");
|
public static PackedScene MyScene { get; } = GD.Load<PackedScene>("MyScene.tscn");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main.cs
|
// Main.cs
|
||||||
public partial class Main : Node
|
public partial class Main : Node
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ Godot stores the project settings in a project.godot file, a plain text file in
|
|||||||
|
|
||||||
To access that dialog, select Project -> Project Settings.
|
To access that dialog, select Project -> Project Settings.
|
||||||
|
|
||||||
Once the window opens, let's select a main scene. Locate the `Application/Run/Main Scene` property and click on it to select 'Hello.tscn'.
|
Once the window opens, let's select a main scene. Locate the `Application/Run/Main Scene` property and click on it to select 'hello.tscn'.
|
||||||
|
|
||||||
The project settings dialog provides a lot of options that can be saved to a project.godot file and shows their default values. If you change a value, a tick appears to the left of its name. This means that the property will be saved in the project.godot file and remembered.
|
The project settings dialog provides a lot of options that can be saved to a project.godot file and shows their default values. If you change a value, a tick appears to the left of its name. This means that the property will be saved in the project.godot file and remembered.
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ use ``area_entered``. However, let's assume our player is a ``CharacterBody2D``
|
|||||||
|
|
||||||
extends Area2D
|
extends Area2D
|
||||||
|
|
||||||
func _on_Coin_body_entered(body):
|
func _on_coin_body_entered(body):
|
||||||
queue_free()
|
queue_free()
|
||||||
|
|
||||||
.. code-tab:: csharp
|
.. code-tab:: csharp
|
||||||
|
|||||||
@@ -219,7 +219,7 @@ To see these examples in action, download the sample project:
|
|||||||
Movement and walls
|
Movement and walls
|
||||||
~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
If you've downloaded the sample project, this example is in "BasicMovement.tscn".
|
If you've downloaded the sample project, this example is in "basic_movement.tscn".
|
||||||
|
|
||||||
For this example, add a ``CharacterBody2D`` with two children: a ``Sprite2D`` and a
|
For this example, add a ``CharacterBody2D`` with two children: a ``Sprite2D`` and a
|
||||||
``CollisionShape2D``. Use the Godot "icon.png" as the Sprite2D's texture (drag it
|
``CollisionShape2D``. Use the Godot "icon.png" as the Sprite2D's texture (drag it
|
||||||
@@ -291,7 +291,7 @@ to get the behavior you want.
|
|||||||
Bouncing/reflecting
|
Bouncing/reflecting
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
What if you don't want a sliding collision response? For this example ("BounceandCollide.tscn"
|
What if you don't want a sliding collision response? For this example ("bounce_and_collide.tscn"
|
||||||
in the sample project), we have a character shooting bullets and we want the bullets to
|
in the sample project), we have a character shooting bullets and we want the bullets to
|
||||||
bounce off the walls.
|
bounce off the walls.
|
||||||
|
|
||||||
@@ -306,7 +306,7 @@ uses the mouse pointer. Here is the code for the Player, using ``move_and_slide(
|
|||||||
|
|
||||||
extends CharacterBody2D
|
extends CharacterBody2D
|
||||||
|
|
||||||
var Bullet = preload("res://Bullet.tscn")
|
var Bullet = preload("res://bullet.tscn")
|
||||||
var speed = 200
|
var speed = 200
|
||||||
|
|
||||||
func get_input():
|
func get_input():
|
||||||
@@ -336,7 +336,7 @@ uses the mouse pointer. Here is the code for the Player, using ``move_and_slide(
|
|||||||
|
|
||||||
public partial class CBExample : CharacterBody2D
|
public partial class CBExample : CharacterBody2D
|
||||||
{
|
{
|
||||||
private PackedScene _bullet = (PackedScene)GD.Load("res://Bullet.tscn");
|
private PackedScene _bullet = (PackedScene)GD.Load("res://bullet.tscn");
|
||||||
public int Speed = 200;
|
public int Speed = 200;
|
||||||
|
|
||||||
public void GetInput()
|
public void GetInput()
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ This would be a basic setup:
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# MyCustomGizmoPlugin.gd
|
# my_custom_gizmo_plugin.gd
|
||||||
extends EditorNode3DGizmoPlugin
|
extends EditorNode3DGizmoPlugin
|
||||||
|
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ This would be a basic setup:
|
|||||||
extends EditorPlugin
|
extends EditorPlugin
|
||||||
|
|
||||||
|
|
||||||
const MyCustomGizmoPlugin = preload("res://addons/my-addon/MyCustomGizmoPlugin.gd")
|
const MyCustomGizmoPlugin = preload("res://addons/my-addon/my_custom_gizmo_plugin.gd")
|
||||||
|
|
||||||
var gizmo_plugin = MyCustomGizmoPlugin.new()
|
var gizmo_plugin = MyCustomGizmoPlugin.new()
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ So the final plugin would look somewhat like this:
|
|||||||
extends EditorNode3DGizmoPlugin
|
extends EditorNode3DGizmoPlugin
|
||||||
|
|
||||||
|
|
||||||
const MyCustomNode3D = preload("res://addons/my-addon/MyCustomNode3D.gd")
|
const MyCustomNode3D = preload("res://addons/my-addon/my_custom_node_3d.gd")
|
||||||
|
|
||||||
|
|
||||||
func _init():
|
func _init():
|
||||||
@@ -177,12 +177,12 @@ for the Node3D nodes we want to target.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# MyCustomGizmoPlugin.gd
|
# my_custom_gizmo_plugin.gd
|
||||||
extends EditorNode3DGizmoPlugin
|
extends EditorNode3DGizmoPlugin
|
||||||
|
|
||||||
|
|
||||||
const MyCustomNode3D = preload("res://addons/my-addon/MyCustomNode3D.gd")
|
const MyCustomNode3D = preload("res://addons/my-addon/my_custom_node_3d.gd")
|
||||||
const MyCustomGizmo = preload("res://addons/my-addon/MyCustomGizmo.gd")
|
const MyCustomGizmo = preload("res://addons/my-addon/my_custom_gizmo.gd")
|
||||||
|
|
||||||
|
|
||||||
func _init():
|
func _init():
|
||||||
@@ -201,7 +201,7 @@ This way all the gizmo logic and drawing methods can be implemented in a new cla
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# MyCustomGizmo.gd
|
# my_custom_gizmo.gd
|
||||||
extends EditorNode3DGizmo
|
extends EditorNode3DGizmo
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ you should remove the instance you have added by calling
|
|||||||
|
|
||||||
|
|
||||||
func _enter_tree():
|
func _enter_tree():
|
||||||
plugin = preload("res://addons/my_inspector_plugin/MyInspectorPlugin.gd").new()
|
plugin = preload("res://addons/my_inspector_plugin/my_inspector_plugin.gd").new()
|
||||||
add_inspector_plugin(plugin)
|
add_inspector_plugin(plugin)
|
||||||
|
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ you should remove the instance you have added by calling
|
|||||||
Interacting with the inspector
|
Interacting with the inspector
|
||||||
------------------------------
|
------------------------------
|
||||||
|
|
||||||
To interact with the inspector dock, your ``MyInspectorPlugin.gd`` script must
|
To interact with the inspector dock, your ``my_inspector_plugin.gd`` script must
|
||||||
extend the :ref:`class_EditorInspectorPlugin` class. This class provides several
|
extend the :ref:`class_EditorInspectorPlugin` class. This class provides several
|
||||||
virtual methods that affect how the inspector handles properties.
|
virtual methods that affect how the inspector handles properties.
|
||||||
|
|
||||||
@@ -112,10 +112,10 @@ specifically add :ref:`class_EditorProperty`-based controls.
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
# MyInspectorPlugin.gd
|
# my_inspector_plugin.gd
|
||||||
extends EditorInspectorPlugin
|
extends EditorInspectorPlugin
|
||||||
|
|
||||||
var RandomIntEditor = preload("res://addons/my_inspector_plugin/RandomIntEditor.gd")
|
var RandomIntEditor = preload("res://addons/my_inspector_plugin/random_int_editor.gd")
|
||||||
|
|
||||||
|
|
||||||
func _can_handle(object):
|
func _can_handle(object):
|
||||||
@@ -149,8 +149,8 @@ specifically add :ref:`class_EditorProperty`-based controls.
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool _ParseProperty(GodotObject @object, Variant.Type type,
|
public override bool _ParseProperty(GodotObject @object, Variant.Type type,
|
||||||
string name, PropertyHint hintType, string hintString,
|
string name, PropertyHint hintType, string hintString,
|
||||||
PropertyUsageFlags usageFlags, bool wide)
|
PropertyUsageFlags usageFlags, bool wide)
|
||||||
{
|
{
|
||||||
// We handle properties of type integer.
|
// We handle properties of type integer.
|
||||||
@@ -197,7 +197,7 @@ followed by ``set_bottom_editor()`` to position it below the name.
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
# RandomIntEditor.gd
|
# random_int_editor.gd
|
||||||
extends EditorProperty
|
extends EditorProperty
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ Add a script to the button like this:
|
|||||||
extends Button
|
extends Button
|
||||||
|
|
||||||
|
|
||||||
func _on_PrintHello_pressed():
|
func _on_print_hello_pressed():
|
||||||
print("Hello from the main screen plugin!")
|
print("Hello from the main screen plugin!")
|
||||||
|
|
||||||
.. code-tab:: csharp
|
.. code-tab:: csharp
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ all you need to initialize your plugin.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# PerlinNoise3D.gd
|
# perlin_noise_3d.gd
|
||||||
@tool
|
@tool
|
||||||
extends VisualShaderNodeCustom
|
extends VisualShaderNodeCustom
|
||||||
class_name VisualShaderNodePerlinNoise3D
|
class_name VisualShaderNodePerlinNoise3D
|
||||||
|
|||||||
@@ -1380,7 +1380,7 @@ By default, all script files are unnamed classes. In this case, you can only
|
|||||||
reference them using the file's path, using either a relative or an absolute
|
reference them using the file's path, using either a relative or an absolute
|
||||||
path. For example, if you name a script file ``character.gd``::
|
path. For example, if you name a script file ``character.gd``::
|
||||||
|
|
||||||
# Inherit from 'Character.gd'.
|
# Inherit from 'character.gd'.
|
||||||
|
|
||||||
extends "res://path/to/character.gd"
|
extends "res://path/to/character.gd"
|
||||||
|
|
||||||
@@ -1399,7 +1399,7 @@ editor. For that, you use the ``class_name`` keyword. You can optionally use
|
|||||||
the ``@icon`` annotation with a path to an image, to use it as an icon. Your
|
the ``@icon`` annotation with a path to an image, to use it as an icon. Your
|
||||||
class will then appear with its new icon in the editor::
|
class will then appear with its new icon in the editor::
|
||||||
|
|
||||||
# Item.gd
|
# item.gd
|
||||||
|
|
||||||
@icon("res://interface/icons/item.png")
|
@icon("res://interface/icons/item.png")
|
||||||
class_name Item
|
class_name Item
|
||||||
@@ -1515,7 +1515,7 @@ explicit constructor::
|
|||||||
|
|
||||||
This is better explained through examples. Consider this scenario::
|
This is better explained through examples. Consider this scenario::
|
||||||
|
|
||||||
# State.gd (inherited class).
|
# state.gd (inherited class).
|
||||||
var entity = null
|
var entity = null
|
||||||
var message = null
|
var message = null
|
||||||
|
|
||||||
@@ -1528,8 +1528,8 @@ This is better explained through examples. Consider this scenario::
|
|||||||
message = m
|
message = m
|
||||||
|
|
||||||
|
|
||||||
# Idle.gd (inheriting class).
|
# idle.gd (inheriting class).
|
||||||
extends "State.gd"
|
extends "state.gd"
|
||||||
|
|
||||||
|
|
||||||
func _init(e=null, m=null):
|
func _init(e=null, m=null):
|
||||||
@@ -1539,17 +1539,17 @@ This is better explained through examples. Consider this scenario::
|
|||||||
|
|
||||||
There are a few things to keep in mind here:
|
There are a few things to keep in mind here:
|
||||||
|
|
||||||
1. If the inherited class (``State.gd``) defines a ``_init`` constructor that takes
|
1. If the inherited class (``state.gd``) defines a ``_init`` constructor that takes
|
||||||
arguments (``e`` in this case), then the inheriting class (``Idle.gd``) *must*
|
arguments (``e`` in this case), then the inheriting class (``idle.gd``) *must*
|
||||||
define ``_init`` as well and pass appropriate parameters to ``_init`` from ``State.gd``.
|
define ``_init`` as well and pass appropriate parameters to ``_init`` from ``state.gd``.
|
||||||
2. ``Idle.gd`` can have a different number of arguments than the base class ``State.gd``.
|
2. ``idle.gd`` can have a different number of arguments than the base class ``state.gd``.
|
||||||
3. In the example above, ``e`` passed to the ``State.gd`` constructor is the same ``e`` passed
|
3. In the example above, ``e`` passed to the ``state.gd`` constructor is the same ``e`` passed
|
||||||
in to ``Idle.gd``.
|
in to ``idle.gd``.
|
||||||
4. If ``Idle.gd``'s ``_init`` constructor takes 0 arguments, it still needs to pass some value
|
4. If ``idle.gd``'s ``_init`` constructor takes 0 arguments, it still needs to pass some value
|
||||||
to the ``State.gd`` base class, even if it does nothing. This brings us to the fact that you
|
to the ``state.gd`` base class, even if it does nothing. This brings us to the fact that you
|
||||||
can pass expressions to the base constructor as well, not just variables, e.g.::
|
can pass expressions to the base constructor as well, not just variables, e.g.::
|
||||||
|
|
||||||
# Idle.gd
|
# idle.gd
|
||||||
|
|
||||||
func _init():
|
func _init():
|
||||||
super(5)
|
super(5)
|
||||||
@@ -1630,7 +1630,7 @@ Example::
|
|||||||
set(value):
|
set(value):
|
||||||
milliseconds = value * 1000
|
milliseconds = value * 1000
|
||||||
|
|
||||||
Using the variable's name to set it inside its own setter or to get it inside its own getter will directly access the underlying member,
|
Using the variable's name to set it inside its own setter or to get it inside its own getter will directly access the underlying member,
|
||||||
so it won't generate infinite recursion and saves you from explicitly declaring another variable::
|
so it won't generate infinite recursion and saves you from explicitly declaring another variable::
|
||||||
|
|
||||||
signal changed(new_value)
|
signal changed(new_value)
|
||||||
@@ -1761,16 +1761,16 @@ signals of nodes like :ref:`class_Button` or :ref:`class_RigidBody3D`.
|
|||||||
|
|
||||||
In the example below, we connect the ``health_depleted`` signal from a
|
In the example below, we connect the ``health_depleted`` signal from a
|
||||||
``Character`` node to a ``Game`` node. When the ``Character`` node emits the
|
``Character`` node to a ``Game`` node. When the ``Character`` node emits the
|
||||||
signal, the game node's ``_on_Character_health_depleted`` is called::
|
signal, the game node's ``_on_character_health_depleted`` is called::
|
||||||
|
|
||||||
# Game.gd
|
# game.gd
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var character_node = get_node('Character')
|
var character_node = get_node('Character')
|
||||||
character_node.health_depleted.connect(_on_Character_health_depleted)
|
character_node.health_depleted.connect(_on_character_health_depleted)
|
||||||
|
|
||||||
|
|
||||||
func _on_Character_health_depleted():
|
func _on_character_health_depleted():
|
||||||
get_tree().reload_current_scene()
|
get_tree().reload_current_scene()
|
||||||
|
|
||||||
You can emit as many arguments as you want along with a signal.
|
You can emit as many arguments as you want along with a signal.
|
||||||
@@ -1779,12 +1779,12 @@ Here is an example where this is useful. Let's say we want a life bar on screen
|
|||||||
to react to health changes with an animation, but we want to keep the user
|
to react to health changes with an animation, but we want to keep the user
|
||||||
interface separate from the player in our scene tree.
|
interface separate from the player in our scene tree.
|
||||||
|
|
||||||
In our ``Character.gd`` script, we define a ``health_changed`` signal and emit
|
In our ``character.gd`` script, we define a ``health_changed`` signal and emit
|
||||||
it with :ref:`Signal.emit() <class_Signal_method_emit>`, and from
|
it with :ref:`Signal.emit() <class_Signal_method_emit>`, and from
|
||||||
a ``Game`` node higher up our scene tree, we connect it to the ``Lifebar`` using
|
a ``Game`` node higher up our scene tree, we connect it to the ``Lifebar`` using
|
||||||
the :ref:`Signal.connect() <class_Signal_method_connect>` method::
|
the :ref:`Signal.connect() <class_Signal_method_connect>` method::
|
||||||
|
|
||||||
# Character.gd
|
# character.gd
|
||||||
|
|
||||||
...
|
...
|
||||||
signal health_changed
|
signal health_changed
|
||||||
@@ -1801,7 +1801,7 @@ the :ref:`Signal.connect() <class_Signal_method_connect>` method::
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# Lifebar.gd
|
# lifebar.gd
|
||||||
|
|
||||||
# Here, we define a function to use as a callback when the
|
# Here, we define a function to use as a callback when the
|
||||||
# character's health_changed signal is emitted.
|
# character's health_changed signal is emitted.
|
||||||
@@ -1824,7 +1824,7 @@ node in this case.
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# Game.gd
|
# game.gd
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var character_node = get_node('Character')
|
var character_node = get_node('Character')
|
||||||
@@ -1862,7 +1862,7 @@ taken by each character on the screen, like ``Player1 took 22 damage.``. The
|
|||||||
damage. So when we connect the signal to the in-game console, we can add the
|
damage. So when we connect the signal to the in-game console, we can add the
|
||||||
character's name in the binds array argument::
|
character's name in the binds array argument::
|
||||||
|
|
||||||
# Game.gd
|
# game.gd
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var character_node = get_node('Character')
|
var character_node = get_node('Character')
|
||||||
@@ -1872,7 +1872,7 @@ character's name in the binds array argument::
|
|||||||
|
|
||||||
Our ``BattleLog`` node receives each element in the binds array as an extra argument::
|
Our ``BattleLog`` node receives each element in the binds array as an extra argument::
|
||||||
|
|
||||||
# BattleLog.gd
|
# battle_log.gd
|
||||||
|
|
||||||
func _on_Character_health_changed(old_value, new_value, character_name):
|
func _on_Character_health_changed(old_value, new_value, character_name):
|
||||||
if not new_value <= old_value:
|
if not new_value <= old_value:
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ who work with your code should always pass an ``Item`` to the
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# In 'Item.gd'.
|
# In 'item.gd'.
|
||||||
class_name Item
|
class_name Item
|
||||||
# In 'Inventory.gd'.
|
# In 'inventory.gd'.
|
||||||
class_name Inventory
|
class_name Inventory
|
||||||
|
|
||||||
|
|
||||||
@@ -123,11 +123,11 @@ script you want to use as a type in a constant:
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
const Rifle = preload("res://player/weapons/Rifle.gd")
|
const Rifle = preload("res://player/weapons/rifle.gd")
|
||||||
var my_rifle: Rifle
|
var my_rifle: Rifle
|
||||||
|
|
||||||
The second method is to use the ``class_name`` keyword when you create.
|
The second method is to use the ``class_name`` keyword when you create.
|
||||||
For the example above, your Rifle.gd would look like this:
|
For the example above, your rifle.gd would look like this:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -235,7 +235,7 @@ You can also use your own nodes as return types:
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
# Inventory.gd
|
# inventory.gd
|
||||||
|
|
||||||
# Adds an item to the inventory and returns it.
|
# Adds an item to the inventory and returns it.
|
||||||
func add(reference: Item, amount: int) -> Item:
|
func add(reference: Item, amount: int) -> Item:
|
||||||
@@ -316,7 +316,7 @@ a ``body_entered`` signal in a dynamic style:
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
func _on_Area2D_body_entered(body):
|
func _on_area_2d_body_entered(body):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
And the same callback, with type hints:
|
And the same callback, with type hints:
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ enemies that the player was spotted.
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
func _on_Player_spotted():
|
func _on_player_spotted():
|
||||||
get_tree().call_group("guards", "enter_alert_mode")
|
get_tree().call_group("guards", "enter_alert_mode")
|
||||||
|
|
||||||
.. code-tab:: csharp
|
.. code-tab:: csharp
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ Here is the code for the player using signals to emit the bullet:
|
|||||||
|
|
||||||
signal shoot(bullet, direction, location)
|
signal shoot(bullet, direction, location)
|
||||||
|
|
||||||
var Bullet = preload("res://Bullet.tscn")
|
var Bullet = preload("res://bullet.tscn")
|
||||||
|
|
||||||
func _input(event):
|
func _input(event):
|
||||||
if event is InputEventMouseButton:
|
if event is InputEventMouseButton:
|
||||||
@@ -113,7 +113,7 @@ Here is the code for the player using signals to emit the bullet:
|
|||||||
[Signal]
|
[Signal]
|
||||||
delegate void ShootEventHandler(PackedScene bullet, Vector2 direction, Vector2 location);
|
delegate void ShootEventHandler(PackedScene bullet, Vector2 direction, Vector2 location);
|
||||||
|
|
||||||
private PackedScene _bullet = GD.Load<PackedScene>("res://Bullet.tscn");
|
private PackedScene _bullet = GD.Load<PackedScene>("res://bullet.tscn");
|
||||||
|
|
||||||
public override void _Input(InputEvent @event)
|
public override void _Input(InputEvent @event)
|
||||||
{
|
{
|
||||||
@@ -138,7 +138,7 @@ In the main scene, we then connect the player's signal (it will appear in the
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
func _on_Player_shoot(Bullet, direction, location):
|
func _on_player_shoot(Bullet, direction, location):
|
||||||
var spawned_bullet = Bullet.instantiate()
|
var spawned_bullet = Bullet.instantiate()
|
||||||
add_child(spawned_bullet)
|
add_child(spawned_bullet)
|
||||||
spawned_bullet.rotation = direction
|
spawned_bullet.rotation = direction
|
||||||
@@ -147,7 +147,7 @@ In the main scene, we then connect the player's signal (it will appear in the
|
|||||||
|
|
||||||
.. code-tab:: csharp
|
.. code-tab:: csharp
|
||||||
|
|
||||||
public void _on_Player_Shoot(PackedScene bullet, Vector2 direction, Vector2 location)
|
public void OnPlayerShoot(PackedScene bullet, Vector2 direction, Vector2 location)
|
||||||
{
|
{
|
||||||
var bulletInstance = (Bullet)bullet.Instantiate();
|
var bulletInstance = (Bullet)bullet.Instantiate();
|
||||||
AddChild(bulletInstance);
|
AddChild(bulletInstance);
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ steps:
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
var scene = load("res://MyScene.tscn")
|
var scene = load("res://my_scene.tscn")
|
||||||
|
|
||||||
.. code-tab:: csharp
|
.. code-tab:: csharp
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ only available with GDScript.
|
|||||||
.. tabs::
|
.. tabs::
|
||||||
.. code-tab:: gdscript GDScript
|
.. code-tab:: gdscript GDScript
|
||||||
|
|
||||||
var scene = preload("res://MyScene.tscn")
|
var scene = preload("res://my_scene.tscn")
|
||||||
|
|
||||||
At that point, ``scene`` is a packed scene resource, not a node. To create the
|
At that point, ``scene`` is a packed scene resource, not a node. To create the
|
||||||
actual node, you need to call :ref:`PackedScene.instantiate()
|
actual node, you need to call :ref:`PackedScene.instantiate()
|
||||||
|
|||||||
@@ -123,10 +123,10 @@ To begin, download the template from here:
|
|||||||
`singleton_autoload_starter.zip <https://github.com/godotengine/godot-docs-project-starters/releases/download/latest-4.x/singleton_autoload_starter.zip>`_
|
`singleton_autoload_starter.zip <https://github.com/godotengine/godot-docs-project-starters/releases/download/latest-4.x/singleton_autoload_starter.zip>`_
|
||||||
and open it in Godot.
|
and open it in Godot.
|
||||||
|
|
||||||
The project contains two scenes: ``Scene1.tscn`` and ``Scene2.tscn``. Each
|
The project contains two scenes: ``scene_1.tscn`` and ``scene_2.tscn``. Each
|
||||||
scene contains a label displaying the scene name and a button with its
|
scene contains a label displaying the scene name and a button with its
|
||||||
``pressed()`` signal connected. When you run the project, it starts in
|
``pressed()`` signal connected. When you run the project, it starts in
|
||||||
``Scene1.tscn``. However, pressing the button does nothing.
|
``scene_1.tscn``. However, pressing the button does nothing.
|
||||||
|
|
||||||
Creating the script
|
Creating the script
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -257,8 +257,8 @@ Finally, we need to fill the empty callback functions in the two scenes:
|
|||||||
|
|
||||||
# Add to 'Scene1.gd'.
|
# Add to 'Scene1.gd'.
|
||||||
|
|
||||||
func _on_Button_pressed():
|
func _on_button_pressed():
|
||||||
Global.goto_scene("res://Scene2.tscn")
|
Global.goto_scene("res://scene_2.tscn")
|
||||||
|
|
||||||
.. code-tab:: csharp
|
.. code-tab:: csharp
|
||||||
|
|
||||||
@@ -267,7 +267,7 @@ Finally, we need to fill the empty callback functions in the two scenes:
|
|||||||
public void OnButtonPressed()
|
public void OnButtonPressed()
|
||||||
{
|
{
|
||||||
var global = GetNode<Global>("/root/Global");
|
var global = GetNode<Global>("/root/Global");
|
||||||
global.GotoScene("res://Scene2.tscn");
|
global.GotoScene("res://scene_2.tscn");
|
||||||
}
|
}
|
||||||
|
|
||||||
and
|
and
|
||||||
@@ -277,8 +277,8 @@ and
|
|||||||
|
|
||||||
# Add to 'Scene2.gd'.
|
# Add to 'Scene2.gd'.
|
||||||
|
|
||||||
func _on_Button_pressed():
|
func _on_button_pressed():
|
||||||
Global.goto_scene("res://Scene1.tscn")
|
Global.goto_scene("res://scene_1.tscn")
|
||||||
|
|
||||||
.. code-tab:: csharp
|
.. code-tab:: csharp
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ and
|
|||||||
public void OnButtonPressed()
|
public void OnButtonPressed()
|
||||||
{
|
{
|
||||||
var global = GetNode<Global>("/root/Global");
|
var global = GetNode<Global>("/root/Global");
|
||||||
global.GotoScene("res://Scene1.tscn");
|
global.GotoScene("res://scene_1.tscn");
|
||||||
}
|
}
|
||||||
|
|
||||||
Run the project and test that you can switch between scenes by pressing
|
Run the project and test that you can switch between scenes by pressing
|
||||||
|
|||||||
Reference in New Issue
Block a user