Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

自动加载与常规节点

Godot offers a feature to automatically load nodes at the root of your project, allowing you to access them globally, that can fulfill the role of a Singleton: Singletons (Autoload). These autoloaded nodes are not freed when you change the scene from code with SceneTree.change_scene_to_file.

在本指南中, 您将学习到何时使用自动加载功能, 以及避免使用该功能的方法.

切割音频问题

其他引擎可能鼓励使用创建管理类, 单例将很多功能组织到一个全局可访问的对象中. 由于节点树和信号,Godot提供了许多避免全局状态的方法.

例如, 假设我们正在构建一个平台游戏, 并希望收集能够播放声音效果的硬币, 那么就有一个节点 AudioStreamPlayer. 如果在 AudioStreamPlayer 已经在播放声音时调用它, 新的声音就会打断第一个声音.

A solution is to code a global, autoloaded sound manager class. It generates a 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. 全局状态 : 一个对象现在负责所有对象的数据. 如果音效有错误, 或没有一个可用的 AudioStreamPlayer , 一切都会崩溃.

  2. 全局访问 : 意味着任何对象都可以从任何地方调用 Sound.play(sound_path) , 便不容易找到错误的来源了.

  3. 全局资源分配 : 由于从一开始就存储了一个 AudioStreamPlayer 节点池, 如果数量太少会遇到bug, 而数量太多则会占用更多的内存.

备注

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.

当您将代码保存在场景中时, 音频可能仅涉及一个或两个脚本.

与之形成对比的是, 每个场景在其内部, 保留尽可能多的 AudioStreamPlayer 节点, 所有这些问题都会消失:

  1. 每个场景管理自己的状态信息. 如果数据有问题, 则只会在该场景中引起问题.

  2. 每个场景只访问自己的节点. 那么如果有一个bug, 很容易找到哪个节点有问题.

  3. 每个场景只分配所需数量的资源.

管理共享功能或数据

使用自动加载的另一个原因可能是您希望在许多场景中重复使用相同的方法或数据.

对于函数,可以使用 GDScript 中的 class_name 关键字创建一种新的 Node 类型,为单个场景提供该功能。

当涉及到数据时, 您可以:

  1. 创建一个新类型的 Resource 来共享数据.

  2. 将数据存储在每个节点可以访问的对象中, 例如使用 owner 属性来访问场景的根节点.

何时应使用自动加载

GDScript supports the creation of static functions using static func. When combined with class_name, this makes it possible to create libraries of helper functions without having to create an instance to call them. The limitation of static functions is that they can't reference member variables, non-static functions or self.

Since Godot 4.1, GDScript also supports static variables using static var. This means you can now share a variables across instances of a class without having to create a separate autoload.

Still, autoloaded nodes can simplify your code for systems with a wide scope. If the autoload 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 dialogue system.

备注

An autoload is not necessarily a singleton. Nothing prevents you from instantiating copies of an autoloaded node. An autoload is only a tool that makes a node load 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 autoloaded node, for example an autoload called Sound, by calling get_node("/root/Sound").