mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-01-03 05:48:42 +03:00
Write nodes_and_scene_instances.rst from scripting_continued.rst
Rewrote the docs Added an intro section about getting nodes and syntactic sugar
This commit is contained in:
@@ -122,122 +122,6 @@ follows, can be applied to nodes:
|
||||
As mentioned before, it's better to use these functions instead of
|
||||
the notification system.
|
||||
|
||||
Creating nodes
|
||||
--------------
|
||||
|
||||
To create a node from code, call the ``.new()`` method, like for any
|
||||
other class-based datatype. For example:
|
||||
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var s
|
||||
func _ready():
|
||||
s = Sprite.new() # Create a new sprite!
|
||||
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
|
||||
used:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
func _someaction():
|
||||
s.free() # Immediately removes the node from the scene and frees it.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public void _SomeAction()
|
||||
{
|
||||
_sprite.Free(); // Immediately removes the node from the scene and frees it.
|
||||
}
|
||||
|
||||
When a node is freed, it also frees all its child nodes. Because of
|
||||
this, manually deleting nodes is much simpler than it appears. Free
|
||||
the base node and everything else in the subtree goes away with it.
|
||||
|
||||
A situation might occur where we want to delete a node that
|
||||
is currently "blocked", because it is emitting a signal or calling a
|
||||
function. This will crash the game. Running Godot
|
||||
with the debugger will often catch this case and warn you about it.
|
||||
|
||||
The safest way to delete a node is by using
|
||||
:ref:`Node.queue_free() <class_Node_method_queue_free>`.
|
||||
This erases the node safely during idle.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
func _someaction():
|
||||
s.queue_free() # Removes the node from the scene and frees it when it becomes safe to do so.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public void _SomeAction()
|
||||
{
|
||||
_sprite.QueueFree(); // Removes the node from the scene and frees it when it becomes safe to do so.
|
||||
}
|
||||
|
||||
Instancing scenes
|
||||
-----------------
|
||||
|
||||
Instancing a scene from code is done in two steps. The
|
||||
first one is to load the scene from your hard drive:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var scene = load("res://myscene.tscn") # Will load when the script is instanced.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
var scene = GD.Load<PackedScene>("res://myscene.tscn"); // Will load when the script is instanced.
|
||||
|
||||
|
||||
Preloading it can be more convenient, as it happens at parse
|
||||
time (GDScript only):
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var scene = preload("res://myscene.tscn") # Will load when parsing the script.
|
||||
|
||||
But ``scene`` is not yet a node. It's packed in a
|
||||
special resource called :ref:`PackedScene <class_PackedScene>`.
|
||||
To create the actual node, the function
|
||||
:ref:`PackedScene.instance() <class_PackedScene_method_instance>`
|
||||
must be called. This will return the tree of nodes that can be added to
|
||||
the active scene:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var node = scene.instance()
|
||||
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
|
||||
kept loaded and ready to use so that you can create as many
|
||||
instances as desired. This is especially useful to quickly instance
|
||||
several enemies, bullets, and other entities in the active scene.
|
||||
|
||||
.. _doc_scripting_continued_class_name:
|
||||
|
||||
Register scripts as classes
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
@@ -37,6 +37,7 @@ below will help you make the most of Godot.
|
||||
debug/index
|
||||
idle_and_physics_processing
|
||||
groups
|
||||
nodes_and_scene_instances
|
||||
cross_language_scripting
|
||||
creating_script_templates
|
||||
change_scenes_manually
|
||||
|
||||
205
tutorials/scripting/nodes_and_scene_instances.rst
Normal file
205
tutorials/scripting/nodes_and_scene_instances.rst
Normal file
@@ -0,0 +1,205 @@
|
||||
.. _doc_nodes_and_scene_instances:
|
||||
|
||||
Nodes and scene instances
|
||||
=========================
|
||||
|
||||
This guide explains how to get nodes, create nodes, add them as a child, and
|
||||
instantiate scenes from code.
|
||||
|
||||
Getting nodes
|
||||
-------------
|
||||
|
||||
You can get a reference to a node by calling the :ref:`Node.get_node()
|
||||
<class_Node_method_get_node>` method. For this to work, the child node must be
|
||||
present in the scene tree. Getting it in the parent node's ``_ready()`` function
|
||||
guarantees that.
|
||||
|
||||
Say you have a scene tree like this, and you want to get a reference to the
|
||||
Sprite and Camera2D nodes to access them in your script.
|
||||
|
||||
.. image:: img/nodes_and_scene_instances_player_scene_example.png
|
||||
|
||||
To do so, you can use the following code.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var sprite
|
||||
var camera2d
|
||||
|
||||
func _ready():
|
||||
sprite = get_node("Sprite")
|
||||
camera2d = get_node("Camera2D")
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
private Sprite _sprite;
|
||||
private Camera2D _camera2d;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
|
||||
_sprite = GetNode<Sprite>("Sprite");
|
||||
_camera2d = GetNode<Camera2D>("Camera2D");
|
||||
}
|
||||
|
||||
Note that you get nodes by their name. For example, if you rename the Sprite
|
||||
node into Skin, the call to get it would have to be ``get_node("Skin")``.
|
||||
|
||||
Node paths
|
||||
----------
|
||||
|
||||
You're not limited to getting a direct child. The ``get_node()`` function
|
||||
supports paths, a bit like when working with a file browser. Add a slash to
|
||||
separate nodes.
|
||||
|
||||
Take the following example scene, with the script attached to the UserInterface
|
||||
node.
|
||||
|
||||
.. image:: img/nodes_and_scene_instances_ui_scene_example.png
|
||||
|
||||
To get the Tween node, you would use the following code.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var tween
|
||||
|
||||
func _ready():
|
||||
tween = get_node("ShieldBar/Tween")
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
private Tween _tween;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
base._Ready();
|
||||
|
||||
_tween = GetNode<Tween>("ShieldBar/Tween");
|
||||
}
|
||||
|
||||
.. note:: As with file paths, you can use ".." to get a parent node. The best
|
||||
practice is to avoid doing that though not to break encapsulation and
|
||||
keep your code organized. You can also start the path with a forward
|
||||
slash to make it absolute, in which case your topmost node would be
|
||||
"/root", the application's predefined root viewport.
|
||||
|
||||
Syntactic sugar
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
You can use two shorthands to shorten your code in GDScript: putting the
|
||||
``onready`` keyword before a member variable makes it initialize right before
|
||||
the ``_ready()`` callback.
|
||||
|
||||
.. code-block:: gdscript
|
||||
|
||||
onready var sprite = get_node("Sprite")
|
||||
|
||||
There is also a short notation for ``get_node()``: the dollar sign, "$". You
|
||||
place it before the name or path of the node you want to get.
|
||||
|
||||
.. code-block:: gdscript
|
||||
|
||||
onready var sprite = $Sprite
|
||||
onready var tween = $ShieldBar/Tween
|
||||
|
||||
Creating nodes
|
||||
--------------
|
||||
|
||||
To create a node from code, call its ``new()`` method like for any other
|
||||
class-based datatype.
|
||||
|
||||
You can store the newly created node's reference in a variable and call
|
||||
``add_child()`` to add it as a child of the node to which you attached the
|
||||
script.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var sprite
|
||||
|
||||
func _ready():
|
||||
var sprite = Sprite.new() # Create a new Sprite.
|
||||
add_child(sprite) # 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 and free it from memory, you can call its ``queue_free()``
|
||||
method. Doing so queues the node for deletion at the end of the current frame
|
||||
after it finished processing. At that point, the engine removes the node from
|
||||
the scene and frees the object in memory.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
sprite.queue_free()
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
_sprite.QueueFree();
|
||||
|
||||
You can alternatively call ``free()`` to immediately destroy the node. You
|
||||
should do this with care as any reference to it will instantly become ``null``.
|
||||
We recommend using ``queue_free()`` unless you know what you're doing.
|
||||
|
||||
When you free a node, it also frees all its children. Thanks to this, to delete
|
||||
an entire branch of the scene tree, you only have to free the topmost parent
|
||||
node.
|
||||
|
||||
Instancing scenes
|
||||
-----------------
|
||||
|
||||
Instancing a scene from code happens in two steps:
|
||||
|
||||
1. Loading the scene from the hard drive.
|
||||
2. Creating an instance of the loaded :ref:`PackedScene <class_PackedScene>`
|
||||
resource.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var scene = load("res://MyScene.tscn")
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
var scene = GD.Load<PackedScene>("res://MyScene.tscn");
|
||||
|
||||
Preloading it can improve the user's experience as it happens when parsing the
|
||||
script. This feature is only available with GDScript.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var scene = preload("res://MyScene.tscn")
|
||||
|
||||
At that point, ``scene`` is a packed scene resource, not a node. To create the
|
||||
actual node, you need to call :ref:`PackedScene.instance()
|
||||
<class_PackedScene_method_instance>`. It returns a tree of nodes that you can
|
||||
add as a child.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
var instance = scene.instance()
|
||||
add_child(instance)
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
var instance = scene.();
|
||||
AddChild(instance);
|
||||
|
||||
The advantage of this two-step process is you can keep a packed scene loaded and
|
||||
create new instances on the fly. For example, to quickly instance several
|
||||
enemies or bullets.
|
||||
Reference in New Issue
Block a user