Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
Usando Árvore de cena¶
Introdução¶
Nos tutoriais anteriores, tudo girava em torno do conceito de nós. Cenas são simplesmente uma coleção de nós. Elas se tornam ativos quando entram na árvore de cena.
Loop principal¶
A maneira como o Godot trabalha internamente é a seguinte. Há a classe OS, que é a única instância que é executada no início. Depois, todos os drivers, servidores, linguagens de script, sistema de cena, etc. são carregados.
Quando a inicialização estiver completa, OS precisa de um MainLoop para ser executado. Até este ponto, tudo isso é funcionamento interno (você pode verificar o arquivo main/main.cpp no código-fonte, se você estiver interessado em ver como isso funciona internamente).
O programa do usuário, ou jogo, inicia no MainLoop. Essa classe tem alguns métodos, para inicialização, ocioso (retorno de chamada com sincronia de quadros), fixo (retorno de chamada com sincronização física) e entrada. Novamente, isso é de baixo nível e ao fazer jogos no Godot, escrever seu próprio MainLoop raramente faz sentido.
SceneTree¶
Uma das maneiras de explicar como Godot funciona é que é um mecanismo de jogo de alto nível sobre um middleware de baixo nível.
O sistema de cena é o mecanismo do jogo, enquanto o OS e os servidores são a API de baixo nível.
O sistema de cena fornece seu próprio loop principal para o SO, SceneTree. Isso é automaticamente instanciado e definido ao executar uma cena, sem necessidade de qualquer trabalho extra.
É importante saber que essa classe existe porque tem alguns usos importantes:
Ele contém o Viewport raiz, para o qual uma cena é adicionada como filha quando é aberta pela primeira vez, para se tornar parte da Árvore da Cena (mais sobre isso a seguir).
Ele contém informações sobre os grupos e tem meios para chamar todos os nós de um grupo ou obter uma lista deles.
Ela contém alguma funcionalidade de estado global, como configurar o modo de pausa ou encerrar o processo.
Quando um nó é parte da Scene Tree, o singleton SceneTree pode ser obtido chamando Node.get_tree().
Viewport raiz¶
A raiz Viewport está sempre no topo da cena. De um nó, ela pode ser obtida de duas maneiras diferentes:
get_tree().root # Access via scene main loop.
get_node("/root") # Access via absolute path.
GetTree().Root // Access via scene main loop.
GetNode("/root"); // Access via absolute path.
Este nó contém a janela de exibição principal. Qualquer coisa que é filho de uma Viewport é desenhada dentro dele por padrão, então faz sentido que o topo de todos os nós seja sempre um nó deste tipo, caso contrário nada seria visto.
Enquanto outras viewports podem ser criadas na cena (para efeitos de tela dividida e tal), esta é a única que nunca é criada pelo usuário. É criado automaticamente dentro do SceneTree.
Árvore de cena¶
Quando um nó é conectado, direta ou indiretamente, à viewport raiz, ele se torna parte da árvore de cena.
Isto significa que, como explicado em tutoriais anteriores, receberá as ligações _enter_tree()
e _ready()
(assim como _exit_tree()
).
Quando os nós entram na Scene Tree, eles se tornam ativos. Eles têm acesso a tudo o que precisam para processar, obter entrada, exibir visuais em 2D e 3D, enviar e receber notificações, reproduzir sons, etc. Quando são removidos da árvore de cena, eles perdem essas habilidades.
Ordem da árvore¶
Most node operations in Godot, such as drawing 2D, processing, or getting notifications are done in tree order, or top to bottom as seen in the editor (also known as pre-order traversal):
For example, the top node in a scene has its _process()
function
called first, then the node below it has its _process()
function called,
then the node below that and so on.
An important exception is the _ready()
function: each parent node has its
_ready()
function called only after all its child nodes have their
_ready()
functions called, so that the parent knows its children are
completely ready to be accessed. This is also known as post-order traversal.
In the above image, NameLabel
would be notified first (but only after its
children, if it had any!), followed by Name
, etc., and Panel
would be
notified last.
The order of operations can also be overridden using the process_priority
node property. Nodes with a lower number are called first. For example, nodes
with the priorities "0, 1, 2, 3" would be called in that order from left to right.
"Tornando-se ativo" entrando na * Scene Tree *¶
Uma cena é carregada do disco ou criada pelo script.
The root node of that scene (only one root, remember?) is added as either a child of the "root" Viewport (from SceneTree), or to any of its descendants.
Every node of the newly added scene will receive the "enter_tree" notification (
_enter_tree()
callback in GDScript) in top-to-bottom order (pre-order traversal).Every node will receive the "ready" notification (
_ready()
callback in GDScript) for convenience, once all its children have received the "ready" notification (post-order traversal).When a scene (or part of it) is removed, they receive the "exit scene" notification (
_exit_tree()
callback in GDScript) in bottom-to-top order (the exact reverse of top-to-bottom order).
Alterando a cena atual¶
After a scene is loaded, you may want to change this scene for another one. One way to do this is to use the SceneTree.change_scene_to_file() function:
func _my_level_was_completed():
get_tree().change_scene_to_file("res://levels/level2.tscn")
public void _MyLevelWasCompleted()
{
GetTree().ChangeSceneToFile("res://levels/level2.tscn");
}
Rather than using file paths, one can also use ready-made PackedScene resources using the equivalent function SceneTree.change_scene_to_packed(PackedScene scene):
var next_scene = preload("res://levels/level2.tscn")
func _my_level_was_completed():
get_tree().change_scene_to_packed(next_scene)
public void _MyLevelWasCompleted()
{
var nextScene = (PackedScene)ResourceLoader.Load("res://levels/level2.tscn");
GetTree().ChangeSceneToPacked(nextScene);
}
These are quick and useful ways to switch scenes but have the drawback that the game will stall until the new scene is loaded and running. At some point in the development of your game, it may be preferable to create proper loading screens with progress bar, animated indicators or threaded (background) loading. This must be done manually using Singletons (Autoload) and Carregamento em segundo plano.