Prefabs
Um prefab é um modelo reutilizável para um objeto de cena e seus filhos — o equivalente na Turian de um prefab da Unity ou de uma instância de cena da Godot. Você cria um objeto uma vez, salva-o como um asset .prefab e depois distribui quantas instâncias desejar em suas cenas. As instâncias permanecem vinculadas à fonte: as edições feitas no prefab fluem de volta para todas as instâncias, exceto pelos campos que uma instância tenha deliberadamente substituído (overridden).
Terminologia. O que você edita no painel Scene Hierarchy é a Cena (Scene) — a árvore de nós ativa e aberta. Quando você a serializa no disco, obtém um Prefab: um asset .prefab com seu próprio GUID/.meta estável. Eles compartilham exatamente a mesma estrutura em disco; um prefab é apenas uma cena salva como um modelo reutilizável e instanciável. Assim, um prefab abre no painel Scene Hierarchy para edição exatamente como qualquer cena, e qualquer cena pode ser instanciada em outra. Seu primeiro objeto é a raiz (root); os filhos ficam aninhados abaixo dele.
Criando um prefab
Duas formas, ambas no editor:
- No painel Scene Hierarchy, clique com o botão direito em um objeto e escolha Create Prefab.
- Arraste um objeto do painel Scene Hierarchy e solte-o no Asset Browser.
De qualquer forma, o editor grava um asset <Nome>.prefab na pasta que o Asset Browser está mostrando no momento, e converte o objeto selecionado (e seus filhos) na primeira instância desse novo prefab. O Inspector passa então a exibir um banner Prefab Instance para ele.
Editando um prefab
Dê um duplo clique em um .prefab no Asset Browser para abri-lo no painel Scene Hierarchy e editá-lo como qualquer cena. Salvar o prefab atualiza suas instâncias na próxima vez em que uma cena que as contenha for aberta (as substituições/overrides são preservadas).
Instanciando
Insira uma cópia nova e vinculada na cena ativa ao:
- Arrastar um
.prefab(ou qualquer cena) do Asset Browser para a Scene Viewport, ou - clicar com o botão direito nele e escolher Instantiate into Scene.
Cada instância recebe seus próprios GUIDs de objeto, mas se lembra de qual prefab ela se originou.
Identificando instâncias
No painel Scene Hierarchy, uma instância de prefab é colorida de azul e sua raiz usa um ícone de caixa, para que uma instância vinculada se destaque de objetos comuns à primeira vista. Selecione qualquer nó na instância para ver o banner Prefab Instance no Inspector.
Substituições (Overrides)
Uma vez instanciada, você pode ajustar a instância livremente no Inspector. Qualquer grupo modificado — name (nome), estado active (ativo), transform ou componentes — é registrado como um override (substituição) e listado no banner Prefab Instance. Os overrides são o que torna cada instância distinta, e eles são preservados quando o prefab de origem é alterado.
Reverter e Aplicar (Revert e Apply)
O banner Prefab Instance oferece duas ações:
- Revert — descarta os overrides da instância e redefine cada campo de volta ao prefab original.
- Apply — envia os valores atuais desta instância para cima, direto para o prefab de origem, e depois propaga a alteração para todas as outras instâncias na cena (cada uma mantendo seus próprios overrides).
Esse é o loop principal de prefabs: edite uma instância, clique em Apply para atualizar o modelo e todas as instâncias irmãs herdarão a alteração, exceto onde tiverem overrides.
Spawning em tempo de execução (runtime)
Os prefabs também são o bloco de construção em tempo de execução (runtime) — o equivalente ao Instantiate / Destroy da Unity. Scripts de gameplay criam (spawn) e removem (despawn) através do contexto Frame:
const std = @import("std");
const engine = @import("engine");
pub const Spawner = struct {
pub const is_component = true;
/// Solte um `.prefab` aqui no Inspector.
prefab: engine.TypedAssetRef(.scene) = .{},
pub fn update(self: *@This(), frame: engine.Frame) void {
// Instantiate(prefab, position, rotation) — position/rotation são opcionais.
if (frame.input.wasPressed("fire")) {
frame.instantiate(self.prefab.slice(), .{ .x = 0, .y = 1, .z = 0 }, null);
}
// Destroy(node) — remove o nó e seus filhos.
for (frame.objects) |*obj| {
if (std.mem.eql(u8, obj.nameSlice(), "Doomed")) frame.destroy(obj);
}
}
};
frame.instantiate(prefab_guid, position, rotation)— enfileira uma nova instância vinculada do prefab (identificado pelo seu GUID de asset, por exemplo, o.slice()de um campoTypedAssetRef(.scene)).positionerotationsão overrides opcionais da transformação da raiz (root) do prefab.frame.destroy(node)— enfileira a remoção de um nó e seus descendentes.
Ambos são postergados (deferred): eles se aplicam no final da atualização atual, nunca no meio de uma iteração, permitindo que um script execute spawn/destroy com segurança ao mesmo tempo que itera sobre frame.objects. As instâncias geradas (spawned) permanecem vinculadas ao seu prefab assim como as colocadas pelo editor. Veja examples/basic-project/assets/PrefabSpawner.zig para uma demonstração executável que registra cada spawn e destroy.
Prefabs aninhados (Nested prefabs)
Um prefab pode conter instâncias de outros prefabs, permitindo que você componha grandes modelos a partir de modelos menores. Para construir um:
- Instancie o prefab A em sua cena (arraste-o para dentro ou clique com o botão direito → Instantiate).
- Adicione um objeto pai e coloque essa instância sob ele (além de qualquer outra coisa que queira).
- Selecione o pai e clique em Create Prefab → o novo prefab B conterá uma instância vinculada de A.
Instanciar B traz o seu A aninhado junto, e cada instância ainda rastreia sua própria fonte de forma independente — editar A e clicar em Apply fluirá para o A aninhado dentro de cada B.
Variantes (ainda não disponível)
As variantes de prefabs — um prefab que herda de outro prefab e aplica suas próprias substituições (overrides) permanentes por cima — ainda não são uma funcionalidade separada. O mais próximo disso hoje em dia é: instancie um prefab, ajuste-o e use Create Prefab a partir dessa instância para obter um prefab novo e independente. Ele não permanecerá vinculado ao original como uma variante real; essa cadeia de herança está planejada para trabalhos futuros.