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.

Alterar cenas manualmente

Às vezes, ajuda ter mais controle sobre como você alterna as cenas de um lado para o outro. Os nós filhos de uma Viewport serão renderizados na imagem que ela gera. Isso é válido até mesmo para nós fora da cena "atual". Autoloads entram nesta categoria, e também cenas que você instancia e adiciona à árvore em tempo de execução:

var simultaneous_scene = preload("res://levels/level2.tscn").instantiate()

func _add_a_scene_manually():
    # This is like autoloading the scene, only
    # it happens after already loading the main scene.
    get_tree().root.add_child(simultaneous_scene)

Para completar o ciclo e trocar a cena antiga pela nova, você tem uma escolha a fazer. Existem muitas estratégias para remover uma cena da visualização da Viewport. As compensações envolvem equilibrar a velocidade da operação e o consumo de memória, bem como equilibrar o acesso e a integridade dos dados.

  1. Deletar a cena existente. SceneTree.change_scene_to_file() e SceneTree.change_scene_to_packed() deletarão a cena atual imediatamente. Você também pode deletar a cena principal. Assumindo que o nome do nó raiz seja "Main", você poderia fazer get_node("/root/Main").free() para deletar a cena inteira.

    • Descarrega memória.

      • Pró: A memória RAM não fica mais carregando o peso morto.

      • Contra: Retornar para aquela cena agora é mais custoso, já que ela deve ser carregada de volta na memória (consome tempo E memória). Não é um problema se não for necessário retornar logo.

      • Contra: Não se tem mais acesso aos dados daquela cena. Não é um problema se não for necessário usar esses dados em breve.

      • Nota: Pode ser útil preservar os dados em uma cena que está prestes a ser deletada, anexando novamente um ou mais de seus nós a uma cena diferente, ou até mesmo diretamente à SceneTree.

    • O processamento é interrompido.

      • Pró: Nenhum nó significa nenhum processamento, processamento de física ou manipulação de entrada. A CPU fica livre para trabalhar no conteúdo da nova cena.

      • Contra: O processamento e a manipulação de entrada daqueles nós não operam mais. Não é um problema se não for necessário usar os dados atualizados.

  2. Ocultar a cena existente. Ao alterar a visibilidade ou a detecção de colisão dos nós, você pode ocultar toda a subárvore de nós da perspectiva do jogador. Use CanvasItem.hide() para ocultar uma cena e CanvasItem.show() para mostrá-la novamente.

    • A memória ainda existe.

      • Pró: Você ainda pode acessar os dados se necessário.

      • Pró: Não há necessidade de mover mais nenhum nó para salvar os dados.

      • Con: More data is being kept in memory, which will become a problem on memory-sensitive platforms like web or mobile.

    • O processamento continua.

      • Pró: Os dados continuam a receber atualizações de processamento, de modo que a cena manterá quaisquer dados dentro dela que dependam do delta time ou dados de quadro atualizados.

      • Pró: Os nós ainda são membros de grupos (já que os grupos pertencem à SceneTree).

      • Contra: A atenção da CPU agora está dividida entre ambas as cenas. Muita carga pode resultar em baixas taxas de quadros (FPS). Você deve ter certeza de testar o desempenho conforme avança para garantir que a plataforma alvo suporte a carga dessa abordagem.

  3. Remover a cena existente da árvore. Atribua uma variável ao nó raiz da cena existente. Em seguida, use Node.remove_child(Node) para desanexar a cena inteira da árvore. Para anexá-la mais tarde, use Node.add_child(Node).

    • A memória ainda existe (prós/contras semelhantes aos de ocultá-la da vista).

    • O processamento para (prós/contras semelhantes aos de deletá-la completamente).

    • Pró: Esta variação de "ocultá-la" é muito mais fácil de mostrar/ocultar. Em vez de potencialmente rastrear múltiplas alterações na cena, você só precisa chamar os métodos add/remove_child. Isso é semelhante a desativar game objects em outras engines.

    • Contra: Ao contrário de apenas ocultá-la da vista, os dados contidos na cena ficarão obsoletos se dependerem do delta time, entrada (input), grupos ou outros dados que são derivados do acesso à SceneTree.

Também há casos em que você pode desejar ter muitas cenas presentes ao mesmo tempo, como adicionar seu próprio singleton em tempo de execução ou preservar os dados de uma cena entre mudanças de cena (adicionando a cena ao nó raiz).

get_tree().root.add_child(scene)

Outro caso pode ser a exibição de múltiplas cenas ao mesmo tempo usando SubViewportContainers. Isso é ideal para renderizar conteúdos diferentes em partes diferentes da tela (por exemplo, minimapas, multiplayer em tela dividida).

Cada opção terá casos em que é mais apropriada, então você deve examinar os efeitos de cada abordagem e determinar qual caminho melhor se adapta à sua situação única.