|
@@ -4,9 +4,9 @@ Autoloads versus regular nodes
|
|
|
==============================
|
|
|
|
|
|
Godot offers a feature to automatically load nodes at the root of your project,
|
|
|
-making allowing you to access them globally, that can fulfill the role of a
|
|
|
-Singleton: :ref:`doc_singletons_autoload`. These auto-loaded nodes are not freed
|
|
|
-when you change the scene from code with ``SceneTree.change_scene``.
|
|
|
+allowing you to access them globally, that can fulfill the role of a Singleton:
|
|
|
+:ref:`doc_singletons_autoload`. These auto-loaded nodes are not freed when you
|
|
|
+change the scene from code with :ref:`SceneTree.change_scene <class_SceneTree_method_change_scene>`..
|
|
|
|
|
|
In this guide, you will learn when to use the Autoload feature, and techniques
|
|
|
you can use to avoid it.
|
|
@@ -20,14 +20,14 @@ many ways to avoid global state thanks to the node tree and signals.
|
|
|
|
|
|
For example, let's say we are building a platformer and want to collect coins
|
|
|
that play a sound effect. There's a node for that: the :ref:`AudioStreamPlayer
|
|
|
-<class_AudioStreamPlayer>`. But if we if call the ``AudioStreamPlayer`` while it
|
|
|
-is already playing a sound, the new sound interrupts the first.
|
|
|
+<class_AudioStreamPlayer>`. But if we call the ``AudioStreamPlayer`` while it is
|
|
|
+already playing a sound, the new sound interrupts the first.
|
|
|
|
|
|
A solution is to code a global, auto-loaded sound manager class. It generates a
|
|
|
-pool of ``AudioStreamPlayer`` that cycle through as each new request for sound
|
|
|
-effects comes in. Say we call that class ``Sound``, you can use it from anywhere
|
|
|
-in your project by calling ``Sound.play("coin_pickup.ogg")``. This solves the
|
|
|
-problem in the short term but causes more problems:
|
|
|
+pool of ``AudioStreamPlayer`` nodes that cycle through as each new request for
|
|
|
+sound effects comes in. Say we call that class ``Sound``, you can use it from
|
|
|
+anywhere in your project by calling ``Sound.play("coin_pickup.ogg")``. This
|
|
|
+solves the problem in the short term but causes more problems:
|
|
|
|
|
|
1. **Global state**: one object is now responsible for all objects' data. If the
|
|
|
``Sound`` class has errors or doesn't have an AudioStreamPlayer available,
|
|
@@ -40,6 +40,15 @@ problem in the short term but causes more problems:
|
|
|
stored from the start, you can either have too few and face bugs, or too many
|
|
|
and use more memory than you need.
|
|
|
|
|
|
+.. note::
|
|
|
+
|
|
|
+ About global access, the problem is that Any code anywhere could pass wrong
|
|
|
+ data to the ``Sound`` autoload in our example. As a result, the domain to
|
|
|
+ explore to fix the bug spans the entire project.
|
|
|
+
|
|
|
+ When you keep code inside a scene, only one one or two scripts may be
|
|
|
+ involved in audio.
|
|
|
+
|
|
|
Contrast this with each scene keeping as many ``AudioStreamPlayer`` nodes as it
|
|
|
needs within itself and all these problems go away:
|
|
|
|
|
@@ -63,7 +72,7 @@ that feature for an individual scene using the :ref:`class_name
|
|
|
|
|
|
When it comes to data, you can either:
|
|
|
|
|
|
-1. Create a new type of :ref:`Resource <class_Resource>` to share the data
|
|
|
+1. Create a new type of :ref:`Resource <class_Resource>` to share the data.
|
|
|
|
|
|
2. Store the data in an object to which each node has access, for example using
|
|
|
the ``owner`` property to access the scene's root node.
|
|
@@ -77,6 +86,8 @@ Auto-loaded nodes can simplify your code in some cases:
|
|
|
database, then an autoload can be a good tool. There is no scripting API in
|
|
|
Godot to create and manage static data otherwise.
|
|
|
|
|
|
+- **Static functions**: creating a library of functions that only return values.
|
|
|
+
|
|
|
- **Systems with a wide scope**: If the singleton is managing its own
|
|
|
information and not invading the data of other objects, then it's a great way to
|
|
|
create systems that handle broad-scoped tasks. For example, a quest or a
|
|
@@ -89,7 +100,10 @@ instead to get autocompletion for a type in your entire project.
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
- Autoload is not exactly a Singleton. Nothing prevents you from instancing
|
|
|
+ Autoload is not exactly a Singleton. Nothing prevents you from instantiating
|
|
|
copies of an auto-loaded node. It is only a tool that makes a node load
|
|
|
- automatically at the root of your scene tree, regardless of your game's node
|
|
|
- structure or the scene you try.
|
|
|
+ automatically as a child of the root of your scene tree, regardless of your
|
|
|
+ game's node structure or which scene you run, e.g. by pressing the ``F6`` key.
|
|
|
+
|
|
|
+ As a result, you can get the auto-loaded node, for example an autoload called
|
|
|
+ ``Sound``, by calling ``get_node("/root/Sound")``.
|