|
@@ -21,11 +21,19 @@ is found in a script. It can be turned off (and back on) with the
|
|
This method will be called every frame drawn, so it's fully depend on the
|
|
This method will be called every frame drawn, so it's fully depend on the
|
|
frames per second (FPS) of the application:
|
|
frames per second (FPS) of the application:
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
func _process(delta):
|
|
func _process(delta):
|
|
# do something...
|
|
# do something...
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ public override void _Process(float delta)
|
|
|
|
+ {
|
|
|
|
+ // do something...
|
|
|
|
+ }
|
|
|
|
+
|
|
The delta parameter describes the time elapsed (in seconds, as a
|
|
The delta parameter describes the time elapsed (in seconds, as a
|
|
floating point) since the previous call to "_process()".
|
|
floating point) since the previous call to "_process()".
|
|
|
|
|
|
@@ -46,7 +54,8 @@ Its execution is done after the physics step on single thread games.
|
|
A simple way to test this is to create a scene with a single Label node,
|
|
A simple way to test this is to create a scene with a single Label node,
|
|
with the following script:
|
|
with the following script:
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
extends Label
|
|
extends Label
|
|
|
|
|
|
@@ -56,6 +65,19 @@ with the following script:
|
|
accum += delta
|
|
accum += delta
|
|
text = str(accum) # text is a built-in label property
|
|
text = str(accum) # text is a built-in label property
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ public class CustomLabel : Label
|
|
|
|
+ {
|
|
|
|
+ private int _accum;
|
|
|
|
+
|
|
|
|
+ public override void _Process(float delta)
|
|
|
|
+ {
|
|
|
|
+ _accum++;
|
|
|
|
+ Text = _accum.ToString();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
Which will show a counter increasing each frame.
|
|
Which will show a counter increasing each frame.
|
|
|
|
|
|
Groups
|
|
Groups
|
|
@@ -70,20 +92,38 @@ ways to do this: the first is from the UI, from the Groups button under the Node
|
|
And the second from code. One useful example would be to tag scenes
|
|
And the second from code. One useful example would be to tag scenes
|
|
which are enemies.
|
|
which are enemies.
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
func _ready():
|
|
func _ready():
|
|
add_to_group("enemies")
|
|
add_to_group("enemies")
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ public override void _Ready()
|
|
|
|
+ {
|
|
|
|
+ base._Ready();
|
|
|
|
+
|
|
|
|
+ AddToGroup("enemies");
|
|
|
|
+ }
|
|
|
|
+
|
|
This way, if the player is discovered sneaking into the secret base,
|
|
This way, if the player is discovered sneaking into the secret base,
|
|
all enemies can be notified about the alarm sounding, by using
|
|
all enemies can be notified about the alarm sounding, by using
|
|
:ref:`SceneTree.call_group() <class_SceneTree_call_group>`:
|
|
:ref:`SceneTree.call_group() <class_SceneTree_call_group>`:
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
func _on_discovered(): # this is a fictional function
|
|
func _on_discovered(): # this is a fictional function
|
|
get_tree().call_group("enemies", "player_was_discovered")
|
|
get_tree().call_group("enemies", "player_was_discovered")
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ public void _OnDiscovered() // this is a fictional function
|
|
|
|
+ {
|
|
|
|
+ GetTree().CallGroup("enemies", "player_was_discovered");
|
|
|
|
+ }
|
|
|
|
+
|
|
The above code calls the function "player_was_discovered" on every
|
|
The above code calls the function "player_was_discovered" on every
|
|
member of the group "enemies".
|
|
member of the group "enemies".
|
|
|
|
|
|
@@ -91,10 +131,15 @@ Optionally, it is possible to get the full list of "enemies" nodes by
|
|
calling
|
|
calling
|
|
:ref:`SceneTree.get_nodes_in_group() <class_SceneTree_get_nodes_in_group>`:
|
|
:ref:`SceneTree.get_nodes_in_group() <class_SceneTree_get_nodes_in_group>`:
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
var enemies = get_tree().get_nodes_in_group("enemies")
|
|
var enemies = get_tree().get_nodes_in_group("enemies")
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ var enemies = GetTree().GetNodesInGroup("enemies");
|
|
|
|
+
|
|
More will be added about
|
|
More will be added about
|
|
:ref:`SceneTree <class_SceneTree>`
|
|
:ref:`SceneTree <class_SceneTree>`
|
|
later.
|
|
later.
|
|
@@ -109,7 +154,8 @@ add a
|
|
:ref:`Object._notification() <class_Object__notification>`
|
|
:ref:`Object._notification() <class_Object__notification>`
|
|
function in your script:
|
|
function in your script:
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
func _notification(what):
|
|
func _notification(what):
|
|
if (what == NOTIFICATION_READY):
|
|
if (what == NOTIFICATION_READY):
|
|
@@ -118,6 +164,24 @@ function in your script:
|
|
var delta = get_process_time()
|
|
var delta = get_process_time()
|
|
print("This is the same as overriding _process()...")
|
|
print("This is the same as overriding _process()...")
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ public override void _Notification(int what)
|
|
|
|
+ {
|
|
|
|
+ base._Notification(what);
|
|
|
|
+
|
|
|
|
+ switch (what)
|
|
|
|
+ {
|
|
|
|
+ case NotificationReady:
|
|
|
|
+ GD.Print("This is the same as overriding _Ready()...");
|
|
|
|
+ break;
|
|
|
|
+ case NotificationProcess:
|
|
|
|
+ var delta = GetProcessDeltaTime();
|
|
|
|
+ GD.Print("This is the same as overriding _Process()...");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
The documentation of each class in the :ref:`Class Reference <toc-class-ref>`
|
|
The documentation of each class in the :ref:`Class Reference <toc-class-ref>`
|
|
shows the notifications it can receive. However, for most cases GDScript
|
|
shows the notifications it can receive. However, for most cases GDScript
|
|
provides simpler overrideable functions.
|
|
provides simpler overrideable functions.
|
|
@@ -128,7 +192,8 @@ Overrideable functions
|
|
Nodes provide many useful overrideable functions, which are described as
|
|
Nodes provide many useful overrideable functions, which are described as
|
|
follows:
|
|
follows:
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
func _enter_tree():
|
|
func _enter_tree():
|
|
# When the node enters the _Scene Tree_, it becomes active
|
|
# When the node enters the _Scene Tree_, it becomes active
|
|
@@ -166,6 +231,46 @@ follows:
|
|
# Called when game is unpaused.
|
|
# Called when game is unpaused.
|
|
pass
|
|
pass
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ public override void _EnterTree()
|
|
|
|
+ {
|
|
|
|
+ // When the node enters the _Scene Tree_, it becomes active
|
|
|
|
+ // and this function is called. Children nodes have not entered
|
|
|
|
+ // the active scene yet. In general, it's better to use _ready()
|
|
|
|
+ // for most cases.
|
|
|
|
+ base._EnterTree();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public override void _Ready()
|
|
|
|
+ {
|
|
|
|
+ // This function is called after _enter_tree, but it ensures
|
|
|
|
+ // that all children nodes have also entered the _Scene Tree_,
|
|
|
|
+ // and became active.
|
|
|
|
+ base._Ready();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public override void _ExitTree()
|
|
|
|
+ {
|
|
|
|
+ // When the node exits the _Scene Tree_, this function is called.
|
|
|
|
+ // Children nodes have all exited the _Scene Tree_ at this point
|
|
|
|
+ // and all became inactive.
|
|
|
|
+ base._ExitTree();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public override void _Process(float delta)
|
|
|
|
+ {
|
|
|
|
+ // This function is called every frame.
|
|
|
|
+ base._Process(delta);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public override void _PhysicsProcess(float delta)
|
|
|
|
+ {
|
|
|
|
+ // This is called every physics frame.
|
|
|
|
+ base._PhysicsProcess(delta);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
As mentioned before, it's best to use these functions.
|
|
As mentioned before, it's best to use these functions.
|
|
|
|
|
|
Creating nodes
|
|
Creating nodes
|
|
@@ -174,21 +279,43 @@ Creating nodes
|
|
To create a node from code, call the .new() method, just like for any
|
|
To create a node from code, call the .new() method, just like for any
|
|
other class based datatype. Example:
|
|
other class based datatype. Example:
|
|
|
|
|
|
-::
|
|
|
|
|
|
+
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
var s
|
|
var s
|
|
func _ready():
|
|
func _ready():
|
|
s = Sprite.new() # create a new sprite!
|
|
s = Sprite.new() # create a new sprite!
|
|
add_child(s) # add it as a child of this node
|
|
add_child(s) # add it as a child of this node
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ private Sprite _sprite;
|
|
|
|
+
|
|
|
|
+ public override void _Ready()
|
|
|
|
+ {
|
|
|
|
+ base._Ready();
|
|
|
|
+
|
|
|
|
+ _sprite = new Sprite(); // create a new sprite!
|
|
|
|
+ AddChild(_sprite); // add it as a child of this node
|
|
|
|
+ }
|
|
|
|
+
|
|
To delete a node, be it inside or outside the scene, "free()" must be
|
|
To delete a node, be it inside or outside the scene, "free()" must be
|
|
used:
|
|
used:
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
func _someaction():
|
|
func _someaction():
|
|
s.free() # immediately removes the node from the scene and frees it
|
|
s.free() # immediately removes the node from the scene and frees it
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ public void _SomeAction()
|
|
|
|
+ {
|
|
|
|
+ _sprite.Free();
|
|
|
|
+ }
|
|
|
|
+
|
|
When a node is freed, it also frees all its children nodes. Because of
|
|
When a node is freed, it also frees all its children nodes. Because of
|
|
this, manually deleting nodes is much simpler than it appears. Just free
|
|
this, manually deleting nodes is much simpler than it appears. Just free
|
|
the base node and everything else in the sub-tree goes away with it.
|
|
the base node and everything else in the sub-tree goes away with it.
|
|
@@ -202,10 +329,18 @@ The safest way to delete a node is by using
|
|
:ref:`Node.queue_free() <class_Node_queue_free>`.
|
|
:ref:`Node.queue_free() <class_Node_queue_free>`.
|
|
This erases the node safely during idle.
|
|
This erases the node safely during idle.
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
func _someaction():
|
|
func _someaction():
|
|
- s.queue_free() # remove the node and delete it while nothing is happening
|
|
|
|
|
|
+ s.queue_free() # immediately removes the node from the scene and frees it
|
|
|
|
+
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ public void _SomeAction()
|
|
|
|
+ {
|
|
|
|
+ _sprite.QueueFree(); // immediately removes the node from the scene and frees it
|
|
|
|
+ }
|
|
|
|
|
|
Instancing scenes
|
|
Instancing scenes
|
|
-----------------
|
|
-----------------
|
|
@@ -213,10 +348,16 @@ Instancing scenes
|
|
Instancing a scene from code is pretty easy and done in two steps. The
|
|
Instancing a scene from code is pretty easy and done in two steps. The
|
|
first one is to load the scene from disk.
|
|
first one is to load the scene from disk.
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
var scene = load("res://myscene.tscn") # will load when the script is instanced
|
|
var scene = load("res://myscene.tscn") # will load when the script is instanced
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ var scene = (PackedScene)ResourceLoader.Load("res://myscene.tscn"); // will load when the script is instanced
|
|
|
|
+
|
|
|
|
+
|
|
Preloading it can be more convenient sometimes, as it happens at parse
|
|
Preloading it can be more convenient sometimes, as it happens at parse
|
|
time.
|
|
time.
|
|
|
|
|
|
@@ -231,11 +372,17 @@ To create the actual node, the function
|
|
must be called. This will return the tree of nodes that can be added to
|
|
must be called. This will return the tree of nodes that can be added to
|
|
the active scene:
|
|
the active scene:
|
|
|
|
|
|
-::
|
|
|
|
|
|
+.. tabs::
|
|
|
|
+ .. code-tab:: gdscript GDScript
|
|
|
|
|
|
var node = scene.instance()
|
|
var node = scene.instance()
|
|
add_child(node)
|
|
add_child(node)
|
|
|
|
|
|
|
|
+ .. code-tab:: csharp
|
|
|
|
+
|
|
|
|
+ var node = scene.Instance();
|
|
|
|
+ AddChild(node);
|
|
|
|
+
|
|
The advantage of this two-step process is that a packed scene may be
|
|
The advantage of this two-step process is that a packed scene may be
|
|
kept loaded and ready to use, so it can be used to create as many
|
|
kept loaded and ready to use, so it can be used to create as many
|
|
instances as desired. This is especially useful to quickly instance
|
|
instances as desired. This is especially useful to quickly instance
|