Snake-case .tscn, .gd and _on_* callbacks

Co-authored-by: Doug Thompson <s-git@dougthompson.co.uk>
This commit is contained in:
Max Hilbrunner
2023-05-18 12:45:55 +02:00
parent 03081e0f14
commit 72c0af46b2
33 changed files with 133 additions and 139 deletions

View File

@@ -94,7 +94,7 @@ Add a script to the ``Mob`` like this:
public:
void _init() {}
void _ready();
void _on_VisibleOnScreenNotifier2D_screen_exited();
void _on_visible_on_screen_notifier_2d_screen_exited();
static void _register_methods();
};
@@ -164,7 +164,7 @@ add this code:
.. code-tab:: 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();
}

View File

@@ -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.)
Click the **Instance** button (represented by a chain link icon) and select your saved
``Player.tscn``.
``player.tscn``.
.. image:: img/instance_scene.webp
@@ -178,9 +178,9 @@ under "Script Variables".
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.
- 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,
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
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.
.. 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
player disappear when hit by a mob.

View File

@@ -411,7 +411,7 @@ with the changing score:
_hud->update_score(score);
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
~~~~~~~~~~~~~~~~~~~

View File

@@ -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
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
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

View File

@@ -81,7 +81,7 @@ You can toggle the model's visibility by clicking the eye icon next to the
|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
some input actions.

View File

@@ -359,14 +359,14 @@ tab at the top of the editor to do so.
|image1|
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
Child Scene*.
|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.
Adding a camera

View File

@@ -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.
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
``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.
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.
Attach a script to the ``Mob``.

View File

@@ -10,7 +10,7 @@ you will have monsters roaming the game board.
|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
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.
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.
.. 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
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*.
|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
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::
.. code-tab:: gdscript GDScript

View File

@@ -74,7 +74,7 @@ see a list of named checkboxes.
|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.
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|
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.
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
<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:
*Signals*, which you've already used, and *Groups*, which allows you to assign
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.
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.

View File

@@ -17,7 +17,7 @@ works well for hitboxes.
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``
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
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.
|image5|
@@ -165,7 +165,7 @@ Code checkpoint
Here are the complete scripts for the ``Main``, ``Mob``, and ``Player`` nodes,
for reference. You can use them to compare and check your code.
Starting with ``Main.gd``.
Starting with ``main.gd``.
.. tabs::
.. code-tab:: gdscript GDScript

View File

@@ -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
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.
|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.
At the bottom of the ``_on_mob_timer_timeout()`` function, add the following
@@ -119,7 +119,7 @@ line:
func _on_mob_timer_timeout():
#...
# 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
@@ -131,9 +131,9 @@ line:
}
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.
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::
.. code-tab:: gdscript GDScript
func _on_Mob_squashed():
func _on_mob_squashed():
score += 1
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`.
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
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
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
rectangle with a uniform color and will serve as an overlay to darken the
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
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.
.. 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
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::
.. code-tab:: gdscript GDScript
@@ -391,7 +385,7 @@ Here is the complete ``Main.gd`` script for reference.
add_child(mob)
# 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():
$MobTimer.stop()

View File

@@ -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
``Character`` node, so we can reuse animations between them.
Open the *Player* scene, select the AnimationPlayer node and open the "float"
animation. Next, click on **Animation > Copy**. Then open ``Mob.tscn``,
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
looping arrows (Animation looping) are also turned on in the animation editor
Open the *Player* scene, select the AnimationPlayer node and open the "float"
animation. Next, click on **Animation > Copy**. Then open ``mob.tscn``,
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
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.
We can change the playback speed based on the creature's ``random_speed``. Open

View File

@@ -11,7 +11,7 @@ into any number of scenes. This feature helps you break down and organize your
game's different components.
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
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.
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
scene.
@@ -64,8 +64,8 @@ Finally, click the Import & Edit button.
.. image:: img/instancing_import_and_edit_button.png
The project contains two packed scenes: ``Main.tscn``, containing walls against
which the ball collides, and ``Ball.tscn``. The Main scene should open
The project contains two packed scenes: ``main.tscn``, containing walls against
which the ball collides, and ``ball.tscn``. The Main scene should open
automatically.
.. 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
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
Ball in the project will see their values update.
.. note:: Changing a property on an instance always overrides values from the
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.
.. image:: img/instancing_physics_material_expand.png

View File

@@ -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
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

View File

@@ -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
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:
.. tabs::
@@ -305,7 +305,7 @@ Our node currently moves by itself. In the next part
Complete script
---------------
Here is the complete ``Sprite2D.gd`` file for reference.
Here is the complete ``sprite_2d.gd`` file for reference.
.. tabs::
.. code-tab:: gdscript GDScript

View File

@@ -11,7 +11,7 @@ Listening to player input
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.
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
@@ -114,7 +114,7 @@ causing the sprite to move forward.
Complete script
---------------
Here is the complete ``Sprite2D.gd`` file for reference.
Here is the complete ``sprite_2d.gd`` file for reference.
.. tabs::
.. code-tab:: gdscript GDScript

View File

@@ -184,7 +184,7 @@ following code, which we saw two lessons ago:
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::
.. 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
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".
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!
Here is the complete ``Sprite2D.gd`` file for reference.
Here is the complete ``sprite_2d.gd`` file for reference.
.. tabs::
.. code-tab:: gdscript GDScript
@@ -354,7 +354,7 @@ Here is the complete ``Sprite2D.gd`` file for reference.
func _ready():
var timer = get_node("Timer")
timer.timeout.connect(_on_Timer_timeout)
timer.timeout.connect(_on_timer_timeout)
func _process(delta):
@@ -367,7 +367,7 @@ Here is the complete ``Sprite2D.gd`` file for reference.
set_process(not is_processing())
func _on_Timer_timeout():
func _on_timer_timeout():
visible = not visible
.. code-tab:: csharp C#

View File

@@ -28,7 +28,7 @@ Creating a MeshLibrary
----------------------
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.
.. image:: img/gridmap_meshlibrary1.png

View File

@@ -65,7 +65,7 @@ and :ref:`set_recording_active() <class_AudioEffectRecord_method_set_recording_a
.. tabs::
.. code-tab:: gdscript GDScript
func _on_RecordButton_pressed():
func _on_record_button_pressed():
if effect.is_recording_active():
recording = effect.get_recording()
$PlayButton.disabled = false
@@ -114,7 +114,7 @@ the recorded stream can be stored into the ``recording`` variable by calling
.. tabs::
.. code-tab:: gdscript GDScript
func _on_PlayButton_pressed():
func _on_play_button_pressed():
print(recording)
print(recording.format)
print(recording.mix_rate)
@@ -145,7 +145,7 @@ To playback the recording, you assign the recording as the stream of the
.. tabs::
.. code-tab:: gdscript GDScript
func _on_SaveButton_pressed():
func _on_save_button_pressed():
var save_path = $SaveButton/Filename.text
recording.save_to_wav(save_path)
$Status.text = "Saved WAV file to: %s\n(%s)" % [save_path, ProjectSettings.globalize_path(save_path)]

View File

@@ -11,7 +11,7 @@ declarative code.
Each system's capabilities are different as a result.
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.
Anonymous types
@@ -150,13 +150,13 @@ with it, and finally adds it as a child of the ``Main`` node:
.. tabs::
.. code-tab:: gdscript GDScript
# Main.gd
# main.gd
extends Node
func _init():
var child = Node.new()
child.name = "Child"
child.script = preload("Child.gd")
child.script = preload("child.gd")
child.owner = self
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");
}
// Main.cs
public partial class Main : Node
{

View File

@@ -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.
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.

View File

@@ -73,7 +73,7 @@ use ``area_entered``. However, let's assume our player is a ``CharacterBody2D``
extends Area2D
func _on_Coin_body_entered(body):
func _on_coin_body_entered(body):
queue_free()
.. code-tab:: csharp

View File

@@ -219,7 +219,7 @@ To see these examples in action, download the sample project:
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
``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
~~~~~~~~~~~~~~~~~~~
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
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
var Bullet = preload("res://Bullet.tscn")
var Bullet = preload("res://bullet.tscn")
var speed = 200
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
{
private PackedScene _bullet = (PackedScene)GD.Load("res://Bullet.tscn");
private PackedScene _bullet = (PackedScene)GD.Load("res://bullet.tscn");
public int Speed = 200;
public void GetInput()

View File

@@ -30,7 +30,7 @@ This would be a basic setup:
::
# MyCustomGizmoPlugin.gd
# my_custom_gizmo_plugin.gd
extends EditorNode3DGizmoPlugin
@@ -45,7 +45,7 @@ This would be a basic setup:
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()
@@ -126,7 +126,7 @@ So the final plugin would look somewhat like this:
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():
@@ -177,12 +177,12 @@ for the Node3D nodes we want to target.
::
# MyCustomGizmoPlugin.gd
# my_custom_gizmo_plugin.gd
extends EditorNode3DGizmoPlugin
const MyCustomNode3D = preload("res://addons/my-addon/MyCustomNode3D.gd")
const MyCustomGizmo = preload("res://addons/my-addon/MyCustomGizmo.gd")
const MyCustomNode3D = preload("res://addons/my-addon/my_custom_node_3d.gd")
const MyCustomGizmo = preload("res://addons/my-addon/my_custom_gizmo.gd")
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

View File

@@ -52,7 +52,7 @@ you should remove the instance you have added by calling
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)
@@ -87,7 +87,7 @@ you should remove the instance you have added by calling
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
virtual methods that affect how the inspector handles properties.
@@ -112,10 +112,10 @@ specifically add :ref:`class_EditorProperty`-based controls.
.. tabs::
.. code-tab:: gdscript GDScript
# MyInspectorPlugin.gd
# my_inspector_plugin.gd
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):
@@ -149,8 +149,8 @@ specifically add :ref:`class_EditorProperty`-based controls.
return true;
}
public override bool _ParseProperty(GodotObject @object, Variant.Type type,
string name, PropertyHint hintType, string hintString,
public override bool _ParseProperty(GodotObject @object, Variant.Type type,
string name, PropertyHint hintType, string hintString,
PropertyUsageFlags usageFlags, bool wide)
{
// We handle properties of type integer.
@@ -197,7 +197,7 @@ followed by ``set_bottom_editor()`` to position it below the name.
.. tabs::
.. code-tab:: gdscript GDScript
# RandomIntEditor.gd
# random_int_editor.gd
extends EditorProperty

View File

@@ -124,7 +124,7 @@ Add a script to the button like this:
extends Button
func _on_PrintHello_pressed():
func _on_print_hello_pressed():
print("Hello from the main screen plugin!")
.. code-tab:: csharp

View File

@@ -32,7 +32,7 @@ all you need to initialize your plugin.
::
# PerlinNoise3D.gd
# perlin_noise_3d.gd
@tool
extends VisualShaderNodeCustom
class_name VisualShaderNodePerlinNoise3D

View File

@@ -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
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"
@@ -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
class will then appear with its new icon in the editor::
# Item.gd
# item.gd
@icon("res://interface/icons/item.png")
class_name Item
@@ -1515,7 +1515,7 @@ explicit constructor::
This is better explained through examples. Consider this scenario::
# State.gd (inherited class).
# state.gd (inherited class).
var entity = null
var message = null
@@ -1528,8 +1528,8 @@ This is better explained through examples. Consider this scenario::
message = m
# Idle.gd (inheriting class).
extends "State.gd"
# idle.gd (inheriting class).
extends "state.gd"
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:
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*
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``.
3. In the example above, ``e`` passed to the ``State.gd`` constructor is the same ``e`` passed
in to ``Idle.gd``.
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
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*
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``.
3. In the example above, ``e`` passed to the ``state.gd`` constructor is the same ``e`` passed
in to ``idle.gd``.
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
can pass expressions to the base constructor as well, not just variables, e.g.::
# Idle.gd
# idle.gd
func _init():
super(5)
@@ -1630,7 +1630,7 @@ Example::
set(value):
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::
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
``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():
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()
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
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
a ``Game`` node higher up our scene tree, we connect it to the ``Lifebar`` using
the :ref:`Signal.connect() <class_Signal_method_connect>` method::
# Character.gd
# character.gd
...
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
# character's health_changed signal is emitted.
@@ -1824,7 +1824,7 @@ node in this case.
::
# Game.gd
# game.gd
func _ready():
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
character's name in the binds array argument::
# Game.gd
# game.gd
func _ready():
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::
# BattleLog.gd
# battle_log.gd
func _on_Character_health_changed(old_value, new_value, character_name):
if not new_value <= old_value:

View File

@@ -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
# In 'Inventory.gd'.
# In 'inventory.gd'.
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
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.
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
And the same callback, with type hints:

View File

@@ -98,7 +98,7 @@ enemies that the player was spotted.
.. tabs::
.. code-tab:: gdscript GDScript
func _on_Player_spotted():
func _on_player_spotted():
get_tree().call_group("guards", "enter_alert_mode")
.. code-tab:: csharp

View File

@@ -94,7 +94,7 @@ Here is the code for the player using signals to emit the bullet:
signal shoot(bullet, direction, location)
var Bullet = preload("res://Bullet.tscn")
var Bullet = preload("res://bullet.tscn")
func _input(event):
if event is InputEventMouseButton:
@@ -113,7 +113,7 @@ Here is the code for the player using signals to emit the bullet:
[Signal]
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)
{
@@ -138,7 +138,7 @@ In the main scene, we then connect the player's signal (it will appear in the
.. tabs::
.. code-tab:: gdscript GDScript
func _on_Player_shoot(Bullet, direction, location):
func _on_player_shoot(Bullet, direction, location):
var spawned_bullet = Bullet.instantiate()
add_child(spawned_bullet)
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
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();
AddChild(bulletInstance);

View File

@@ -188,7 +188,7 @@ steps:
.. tabs::
.. code-tab:: gdscript GDScript
var scene = load("res://MyScene.tscn")
var scene = load("res://my_scene.tscn")
.. code-tab:: csharp
@@ -201,7 +201,7 @@ only available with GDScript.
.. tabs::
.. 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
actual node, you need to call :ref:`PackedScene.instantiate()

View File

@@ -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>`_
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
``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
~~~~~~~~~~~~~~~~~~~~~
@@ -257,8 +257,8 @@ Finally, we need to fill the empty callback functions in the two scenes:
# Add to 'Scene1.gd'.
func _on_Button_pressed():
Global.goto_scene("res://Scene2.tscn")
func _on_button_pressed():
Global.goto_scene("res://scene_2.tscn")
.. code-tab:: csharp
@@ -267,7 +267,7 @@ Finally, we need to fill the empty callback functions in the two scenes:
public void OnButtonPressed()
{
var global = GetNode<Global>("/root/Global");
global.GotoScene("res://Scene2.tscn");
global.GotoScene("res://scene_2.tscn");
}
and
@@ -277,8 +277,8 @@ and
# Add to 'Scene2.gd'.
func _on_Button_pressed():
Global.goto_scene("res://Scene1.tscn")
func _on_button_pressed():
Global.goto_scene("res://scene_1.tscn")
.. code-tab:: csharp
@@ -287,7 +287,7 @@ and
public void OnButtonPressed()
{
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