Cenas

Esta página foi traduzida automaticamente e pode conter erros. Encontrou um problema? Use o link "Edit this page" para ajudar a corrigir.

Uma cena (scene) da Turian pode ser instanciada como uma árvore de nós (node tree, como uma cena da Godot ou um prefab da Unity). O Scene Manager adiciona a outra metade — tratando as cenas da mesma forma que o SceneManager da Unity faz: unidades nomeadas e endereçáveis que são carregadas e descarregadas como um todo, com cenas aditivas (additive), objetos persistentes, carregamento assíncrono (async loading) e eventos de ciclo de vida.

A cena de inicialização (boot scene) vem das suas Configurações do Projeto (Project Settings) (first_scene); a partir daí, seu jogo controla as transições de cena através do serviço engine.SceneManager.


Acessando o manager a partir de um script

O manager é injetado como um serviço, acessível a partir do Frame de qualquer componente:

const engine = @import("engine");

pub const SceneDirector = struct {
    pub const is_component = true;

    // Configurado no Inspector, não hardcoded — veja "Referências de cenas como campos".
    level_a: engine.TypedAssetRef(.scene) = .{},
    level_b: engine.TypedAssetRef(.scene) = .{},

    pub fn start(self: *SceneDirector, frame: engine.Frame) void {
        const mgr = frame.service(engine.SceneManager) orelse return;
        // Mantém a cena de inicialização (câmera/diretor) viva ao alternar de fase.
        if (mgr.getActiveScene()) |boot| mgr.setScenePersistent(boot, true);
        mgr.requestLoad(self.level_a.guid(), .additive);
    }

    pub fn update(self: *SceneDirector, frame: engine.Frame) void {
        const mgr = frame.service(engine.SceneManager) orelse return;
        if (frame.input.wasKeyPressed(.num_2)) mgr.requestLoad(self.level_b.guid(), .single);
    }
};

Referências de cenas como campos

Em vez de colar os GUIDs das cenas no seu código, declare um campo engine.TypedAssetRef(.scene). O Inspector renderiza um seletor de asset de cena (scene-asset picker) para ele (arraste uma cena do Asset Browser, ou use o botão ... para escolher a partir de uma lista filtrada de cenas). O GUID selecionado é salvo no arquivo da cena e reidratado de volta no campo em tempo de execução (runtime), de modo que o script o lê com field.guid():

next_scene: engine.TypedAssetRef(.scene) = .{},

pub fn update(self: *@This(), frame: engine.Frame) void {
    const mgr = frame.service(engine.SceneManager) orelse return;
    if (frame.input.wasKeyPressed(.space))
        mgr.requestLoad(self.next_scene.guid(), .single);
}

Esse é o mesmo mecanismo de referência a assets tipados usado para meshes e materiais, especializado para cenas — os designers configuram as transições sem precisar tocar no código.

Modos de carregamento (Load modes)

Modo Comportamento
.single Descarrega cada cena não persistente e depois carrega a nova — a clássica transição de "próxima fase".
.additive Carrega a cena ao lado das que já estão carregadas.

Cenas persistentes (DontDestroyOnLoad)

mgr.setScenePersistent(handle, true) marca uma cena para sobreviver a carregamentos .single. Coloque sua câmera, HUD e controles em uma cena persistente de inicialização (bootstrap scene) e eles sobreviverão a todas as transições de fases — o equivalente do Scene Manager ao DontDestroyOnLoad da Unity. (Nós individuais também podem ser movidos para uma cena persistente dedicada com markDontDestroyOnLoad.)

Requisições adiadas (Deferred requests)

Os scripts requisitam alterações de cena com requestLoad / requestUnload. Estas são aplicadas no final do frame, nunca no meio de uma atualização — permitindo que um script descarregue com segurança a própria cena em que está rodando. (loadScene / unloadScene também estão disponíveis para controle imediato do lado do host).

Rastreamento e consultas (Tracking & queries)

const active = mgr.getActiveScene();          // ?SceneHandle
var buf: [engine.SCENE_MANAGER_MAX_SCENES]engine.SceneHandle = undefined;
const loaded = mgr.getLoadedScenes(&buf);     // []SceneHandle
const here = mgr.findById(LEVEL_A);           // ?SceneHandle
const ok = mgr.isLoaded(handle);

Eventos de ciclo de vida

Inscreva-se para ser notificado quando as cenas mudam de estado:

mgr.subscribe(onSceneEvent, ctx); // dispara ao carregar / descarregar / ativar / desativar

Carregamento assíncrono (Async loading)

Cenas grandes podem carregar em uma thread de trabalho (worker thread) sem bloquear o frame:

const h = try mgr.loadSceneAsync(io, id, .single);
// ... continua renderizando uma tela de carregamento ...
if (mgr.isReady(h)) _ = mgr.finishAsync(io, h, .single);

Tratamento de erros

Carregamentos síncronos retornam erros tipados (NoLoader, LoadFailed, TooManyScenes); para carregamentos assíncronos, o motivo de erro específico da cena está disponível via mgr.getError(handle).

Exemplo

Veja examples/scene-management/ no repositório para uma demonstração completa e executável de boot + inicialização persistente + carregamento aditivo (additive load) + alternância em tempo de execução.


← Toda a documentação Editar esta página