Organização de cenas no Godot 4
Cena, script ou Resource
- Cena (
.tscn): uma árvore reutilizável de nós com seus próprios recursos: um jogador, um inimigo, um item coletável, um painel de UI, uma fase. Qualquer coisa que você coloque mais de uma vez ou queira executar sozinha (F6) é uma cena. - Script (
.gd): comportamento anexado a um nó. Anexe-o à raiz da cena que ele controla, não a um pai que acessa o nó de fora. - Script de Resource (
extends Resourcecomclass_name): dados sem um nó, como estatísticas de itens, definições de ondas ou dados de salvamento, editados no Inspetor e salvos como.tres.
Uma cena deve funcionar quando executada sozinha. Se ela precisar de algo externo (um alvo, um pai para spawn), exponha isso com @export ou um sinal em vez de cadeias de get_parent().
Instanciando cenas
extends Node2D
@export var cena_inimigo: PackedScene
@export var pai_spawn: Node2D
func spawnar_inimigo(em: Vector2) -> void:
var inimigo := cena_inimigo.instantiate() as Node2D
inimigo.position = em
pai_spawn.add_child(inimigo)
func carregar_fase(caminho: String) -> void:
var empacotado := load(caminho) as PackedScene
if empacotado == null:
push_error("Fase não encontrada: " + caminho)
return
get_tree().change_scene_to_packed(empacotado)
@export var x: PackedSceneé definido no Inspetor e sobrevive a movimentações de arquivo, pois a cena armazena a referência.const BALA := preload("res://bala.tscn")é resolvido em tempo de análise: um arquivo ausente causa um erro de análise (Preload file "res://bala.tscn" does not exist.). Bom para assets fixos.load()é resolvido em tempo de execução e retornanullcom um erro se o caminho estiver errado. Use-o para caminhos construídos em tempo de execução.instantiate()(não oinstance()do Godot 3) retorna umNode; faça cast para o tipo que você precisa. Libere instâncias comqueue_free().
Encontrando nós
extends Control
@onready var titulo: Label = %Titulo
@onready var botao_iniciar: Button = %BotaoIniciar
@onready var musica: AudioStreamPlayer = $Musica
@onready var dica_opcional: Label = get_node_or_null("Dica")
func _ready() -> void:
titulo.text = "Menu principal"
botao_iniciar.grab_focus()
if dica_opcional:
dica_opcional.visible = false
musica.play()
$Caminhoéget_node("Caminho"), relativo a este nó. Gera erro se o nó estiver ausente; useget_node_or_null()para nós opcionais.%Nomealcança um nó marcado como "Access as Unique Name" (clique direito no dock de Cenas) em qualquer lugar da mesma cena, portanto sobrevive a reparentalização dentro da cena. Não alcança cenas filhas instanciadas: use$Filho/%Nome, ou%Filho/%Nomequando a instância também for única.- Variáveis
@onreadysão atribuídas imediatamente antes de_ready(). Elas sãonullem_init()e_enter_tree(). _ready()executa nos filhos antes dos pais, portanto o_ready()de um pai pode usar seus filhos, mas o_ready()de um filho não deve depender de o pai estar pronto.- Tipifique variáveis
@onready(: Label) para que o analisador verifique nomes de membros;$Label.txtem um caminho não tipificado só é capturado em tempo de execução.
Grupos
Grupos marcam nós entre cenas. Adicione-os no dock de Nós (aba Grupos) ou em código, depois consulte a árvore:
extends Node
func _ready() -> void:
add_to_group("inimigos")
func alertar_todos_inimigos() -> void:
get_tree().call_group("inimigos", "set_alerted", true)
for inimigo in get_tree().get_nodes_in_group("inimigos"):
print(inimigo.name)
var jogador := get_tree().get_first_node_in_group("jogador") as Node2D
if jogador:
print("Jogador em ", jogador.global_position)
call_group() chama imediatamente no Godot 4. Use get_tree().call_group_flags(SceneTree.GROUP_CALL_DEFERRED, ...) para adiar.
Autoloads
Um autoload é um nó criado antes da cena principal e mantido entre mudanças de cena. Use-o para estado que sobrevive a uma única cena (configurações, dados salvos, um trocador de cenas) e para um barramento de eventos apenas com sinais. Registre-o em Projeto > Configurações do Projeto > Globais > Autoload; project.godot então contém:
[autoload]
Eventos="*res://autoload/eventos.gd"
O * significa que "Ativar" está marcado, então scripts podem usar o nome diretamente (Eventos.jogador_morreu.emit()). Não use free() ou queue_free() em um autoload. Mantenha poucos autoloads: qualquer coisa que pertença a uma fase deve viver na cena dessa fase.
Nota para ferramentas: godot --check-only --script não carrega autoloads, então um script que usa um nome de autoload relata Identifier not found: Eventos lá mesmo que funcione normalmente. Verifique esses scripts executando a cena (veja a skill godot-verify).
class_name
class_name Jogador registra um tipo global, então outros scripts podem escrever var jogador: Jogador e obter verificação de membros. O editor mantém um cache de classes global em .godot/; após adicionar um class_name fora do editor, abra o editor ou execute godot --headless --path . --import antes de verificar scripts que o usam.
UIDs, arquivos .uid e movimentação de arquivos
O Godot 4 referencia recursos por UID além do caminho. Cenas e recursos armazenam seu próprio UID no cabeçalho do arquivo, assets importados em seu arquivo .import, e desde o Godot 4.4 scripts e shaders recebem um arquivo companheiro (jogador.gd.uid, agua.gdshader.uid). Uma referência salva pelo editor se parece com:
[ext_resource type="Script" uid="uid://dxxoiuob4eoum" path="res://gerenciador_jogo.gd" id="1_feb5d"]
Regras:
- Faça commit dos arquivos
*.uidno controle de versão. Não os adicione ao.gitignore. - Mova e renomeie arquivos no dock do Sistema de Arquivos do Godot quando possível; ele atualiza as referências.
- Ao mover um script ou shader fora do Godot (shell, IDE, agente), mova seu arquivo
.uidjunto, então abra o editor ou executegodot --headless --path . --importpara que o cache de UID aprenda o novo caminho. Até essa varredura, o caminho antigo ainda é usado e o carregamento falha. - Se o arquivo
.uidfor deixado para trás, o Godot gera um novo UID para o script movido e as cenas que referenciavam o antigo usam o caminho desatualizado:WARNING: ... invalid UID: uid://... - using text path instead: res://caminho/antigo.gd, depoisERROR: ... referenced non-existent resource. - Ao escrever um
.tscnmanualmente, não invente valoresuid=. Omita o atributo e use umpathcorreto; o editor adiciona UIDs quando salvar a cena em seguida. - Uma cena Godot 4 escrita à mão começa com
[gd_scene format=3]e referencia recursos por id de string:[ext_resource type="Script" path="res://principal.gd" id="1_principal"], depoisscript = ExtResource("1_principal")no nó. Nós filhos precisam deparent="."ou um caminho a partir da raiz. Godot 4.7 também escreveunique_id=em nós; omita ao escrever manualmente. load("uid://...")epreload("uid://...")aceitam strings de UID. Copie um UID do menu de contexto do dock do Sistema de Arquivos;ResourceUID.id_to_text(ResourceLoader.get_resource_uid(caminho))o retorna via código.
Erros comuns
- Subir com
get_parent().get_parent()ou caminhos absolutos como/root/Main/Player. Exporte uma referência, use um grupo ou emita um sinal. - Usar um nó em
_init()ou antes de ele entrar na árvore. - Codificar caminhos
res://para cenas em muitos scripts em vez de exportar umPackedScene. - Mover arquivos
.gdsem seus arquivos.uid, ou ignorar*.uidno git. - Transformar tudo em autoload por conveniência.