Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Autoloads versus nós normais

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.

Neste guia, você aprenderá quando usar a funcionalidade Autoload e as técnicas que você pode usar para evitá-lo.

O problema do corte de áudio

Outros motores podem encorajar o uso da criação de classes de gerenciador, singletons que organizam muita funcionalidade em um objeto globalmente acessível. O Godot oferece muitas maneiras de evitar o estado global graças à árvore de nós e aos sinais.

Por exemplo, digamos que estamos construindo um jogo de plataforma e queremos coletar moedas que reproduzam um efeito sonoro. Há um nó para isso: o AudioStreamPlayer. Mas se chamarmos o AudioStreamPlayer enquanto ele já está tocando um som, o novo som interrompe o primeiro.

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. Estado global: um objeto agora é responsável pelos dados de todos os objetos. Se a classe Sound tem erros ou não tem um AudioStreamPlayer disponível, todos os nós que o chamam podem quebrar.

  2. Acesso global: agora que qualquer objeto pode chamar Sound.play(sound_path) de qualquer lugar, não há mais uma maneira fácil de encontrar a origem de um bug.

  3. Alocação global de recursos*: com um conjunto de nós AudioStreamPlayer armazenados desde o início, você pode ou ter muito poucos e enfrentar bugs, ou muitos e utilizar mais memória do que você precisa.

Nota

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.

Quando você mantém o código dentro de uma cena, apenas um ou dois scripts podem estar envolvidos no áudio.

Contraste isto com cada cena mantendo tantos nós AudioStreamPlayer quantos forem necessários dentro de si e todos estes problemas desaparecem:

  1. Cada cena gerencia suas próprias informações de estado. Se houver um problema com os dados, isso causará problemas apenas naquela cena.

  2. Cada cena acessa apenas seus próprios nós. Agora, se houver um bug, é fácil descobrir qual nó é o culpado.

  3. Cada cena aloca exatamente a quantidade de recursos de que precisa.

Gestão de funcionalidades ou dados compartilhados

Outra razão para usar um Autoload pode ser que você queira reutilizar o mesmo método ou dados em muitas cenas.

No caso de funções, você pode criar um novo tipo de Node que fornece esse recurso para uma cena individual utilizando a palavra-chave class_name em GDScript.

Quando se trata de dados, você pode:

  1. Cria um novo tipo de Resource para compartilhar os dados.

  2. Armazenar os dados em um objeto ao qual cada nó tem acesso, por exemplo utilizando a propriedade owner para acessar o nó raiz da cena.

Quando você deve usar um Autoload

GDScript suporta a criação de funções static usando static func`. Quando combinado com class_name, isso torna possível criar bibliotecas de funções auxiliares sem ter que criar uma instância para chamá-los. A limitação de funções estáticas é que elas não podem referenciar variáveis de membros, funções não estáticas ou self.

A partir do Godot 4.1, GDScript também suporta variáveis static usando static var. Isso significa que agora você pode compartilhar uma variável em instâncias de uma classe sem ter que criar um autoload separado.

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.

Nota

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").