Pular para o conteúdo principal
Versão: 5.0.x

Scene Ref

O SceneRef é uma referência a uma cena — o que você passa para toda operação. Uma única struct cobre todas as formas de nomear uma cena.

Uma struct para todo tipo de referência​

public readonly struct SceneRef
{
public SceneRefKind Kind { get; }
public bool IsValid { get; }

public string Key { get; }
public int BuildIndex { get; }
public Scene Scene { get; }
}

Cada tipo vive no seu próprio campo, com Kind dizendo qual deles está definido. É isso que evita que um índice de build sofra boxing para object e seja convertido de volta a cada chamada.

Você raramente escreve SceneRef por conta própria, porque tudo converte implicitamente:

SceneRef byName = "my-scene"; // Key
SceneRef byIndex = 1; // BuildIndex
SceneRef byScene = someLoadedScene; // Scene
SceneRef address = SceneRef.Address("my-scene");
SceneRef asset = myAssetReference; // AssetReference

Tipos de Scene Ref​

  • Key — uma string simples: nome, caminho ou endereço. Ainda não resolvida; veja abaixo.
  • BuildIndex — o índice de build de uma cena.
  • Scene — a struct de uma cena carregada (usada apenas para descarregar cenas).
  • Address — um endereço dos Addressables, declarado explicitamente.
  • AssetReference — o AssetReference Addressable de uma cena.
  • None — não aponta para nada. É o que default(SceneRef) representa.

Como uma string é resolvida​

Você nunca escolhe entre uma API addressable e uma não-addressable. Uma string simples chega como Key, e o SceneRefResolver decide o que ela significa:

  1. As Build Settings vencem. Se a string corresponde a um nome ou caminho de cena nas Build Settings, ela vira um BuildIndex.
  2. Caso contrário, os Addressables são consultados, e ela vira um Address.
  3. Se nenhum dos dois a tiver, a resolução lança uma exceção indicando os dois lugares onde procurou.
MySceneManager.LoadAsync("my-scene"); // build settings, ou Addressables
MySceneManager.LoadAsync(SceneRef.Address("my-scene")); // forçado, e o caminho rápido

SceneRef.Address(...) é a forma de forçar o resultado, e pula a consulta por completo.

atenção

A resolução é comportamento observável, não um detalhe de implementação. Adicionar uma cena às Build Settings mais tarde pode fazer uma string passar dos Addressables para o backend padrão sem nenhuma mudança de código do seu lado.

Uma chave que corresponde a ambos é reportada em Warning através do SceneManagerLog, e a primeira resolução de cada chave é reportada em Verbose, então isso é diagnosticável, e não um mistério.

info

Só uma chave nunca vista antes, e que não está nas Build Settings, precisa do catálogo dos Addressables — e só esse caso suspende a execução. Toda resposta fica em cache, então cada chave é consultada no máximo uma vez, mas a primeira resolução addressable por string paga, sim, a latência de inicialização do catálogo.

Descarregando​

Ao descarregar uma cena, o CoreSceneManager procura entre suas cenas carregadas qualquer uma que corresponda ao SceneRef, seja pelo handle da cena, nome, caminho, build index ou referência addressable.

Isso significa que a forma preferencial de descarregar cenas é passando a própria Scene, pois ela contém uma referência direta ao alvo; ainda assim, você pode usar qualquer tipo.

atenção

Se você tiver várias cenas idênticas carregadas, descarregar por qualquer coisa que não seja uma Scene vai descarregar a última cena carregada que corresponda à referência.

info

Ao descarregar cenas addressable, seus recursos serão liberados chamando Addressables.UnloadSceneAsync internamente.

Scene Parameters​

SceneParameters envolve um ou vários SceneRef, além de qual deles deve ficar ativo. Ele também converte implicitamente, então na maior parte do tempo você passa a cena direto para a operação e nunca nomeia a struct:

MySceneManager.LoadAsync("my-scene"); // uma, não ativada
MySceneManager.LoadAsync(new SceneParameters("my-scene", true)); // uma, ativada
MySceneManager.LoadAsync(new[] { "scene-a", "scene-b" }); // várias, nenhuma ativada
MySceneManager.LoadAsync(new SceneParameters(new SceneRef[] { "scene-a", "scene-b" }, 1));
nota

Uma conversão simples nunca define a cena como ativa — você precisa pedir isso explicitamente. A exceção é TransitionAsync, que sempre ativa alguma coisa, porque descarrega a cena de onde você veio.