Autoloads versus nós normais¶
O Godot oferece um recurso para carregar automaticamente nós na raiz do seu projeto, permitindo que você os acesse globalmente, que pode cumprir o papel de um Singleton: Singletons (Carregamento Automático). Estes nós auto-carregados não são liberados quando você muda a cena pelo código com SceneTree.change_scene.
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.
Uma solução é codificar uma classe de gestão de som global e auto-carregada. Ele gera um conjunto de nós AudioStreamPlayer
que se movimentam à medida que cada nova solicitação de efeitos sonoros chega. Digamos que chamamos essa classe Sound
, você pode utilizá-la de qualquer lugar do seu projeto chamando Sound.play("coin_pickup.ogg")
. Isto resolve o problema a curto prazo, mas causa mais problemas:
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.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.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
Sobre o acesso global, o problema é que qualquer código em qualquer lugar pode passar dados errados para o autoload Sound
no nosso exemplo. Como resultado, o domínio a explorar para corrigir o bug abrange todo o projeto.
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:
Cada cena gerencia suas próprias informações de estado. Se houver um problema com os dados, isso causará problemas apenas naquela cena.
Cada cena acessa apenas seus próprios nós. Agora, se houver um bug, é fácil descobrir qual nó é o culpado.
Cada cena aloca exatamente a quantidade de recursos de que precisa.
Quando você deve usar um Autoload¶
Nós carregados automaticamente podem simplificar seu código em alguns casos:
Dados estáticos: se você precisa de dados exclusivos de uma classe, como um banco de dados, então um auto-carregamento pode ser uma boa ferramenta. Não há API de scripting no Godot para criar e gerenciar dados estáticos de outra forma.
Funções estáticas: criar uma biblioteca de funções que só retornam valores.
Sistemas com amplo escopo: se o singleton está gerenciando suas próprias informações e não invadindo os dados de outros objetos, então é uma ótima maneira de criar sistemas que lidam com tarefas de amplo escopo. Por exemplo, uma quest ou um sistema de diálogo.
Até o Godot 3.1, outro uso era apenas por conveniência: os autoloads têm uma variável global para seu nome gerada no GDScript, permitindo que você os chame a partir de qualquer arquivo de script em seu projeto. Mas agora, você pode usar a palavra-chave class_name
para obter o preenchimento automático de um tipo em todo o seu projeto.
Nota
Autoload não é exatamente um Singleton. Nada o impede de instanciar cópias de um nó carregado automaticamente. É apenas uma ferramenta que faz um nó carregar automaticamente como um filho da raiz da sua árvore de cenas, independentemente da estrutura do seu jogo ou da cena que você executar, por exemplo, pressionando a tecla F6.
Como resultado, você pode obter o nó carregado automaticamente, por exemplo, um autoload chamado Sound
, chamando get_node("/root/Sound")
.