Aprendizado da estrutura Unity - gerenciador de troca de cena

Cena de atividade

Os objetos do jogo instanciados por meio de scripts são gerados na cena ativa.

Qual cena é a cena ativa, o camarote atual usará o camarote dessa cena.

Apenas uma cena pode ser a cena ativa.

Clique com o botão direito em uma cena na hierarquia e clique em "Definir cena ativa" para definir manualmente esta cena como cena ativa. Você também pode usar o método SceneManager.SetActiveScene para definir uma cena carregada como cena ativa.

Carregamento assíncrono

O código relacionado ao AsyncOperation deve ser escrito em uma corrotina.

Nome do objeto AsyncOperation = SceneManager.LoadSceneAsync (string nome da cena)
ativa o carregamento assíncrono de cenas e armazena informações de carregamento assíncrono em objetos AsyncOperation.

O tipo AsyncOperation object.allowSceneActivation
retorna um tipo bool, indicando se a cena deve ser ativada imediatamente após o carregamento da cena.
Um valor true significa que assim que a cena for carregada de forma assíncrona, a cena será ativada imediatamente.
Um valor falso significa que a cena não será ativada mesmo que a cena seja carregada. A cena não será ativada até que o valor desta variável seja alterado para verdadeiro novamente usando código.

O tipo AsyncOperation object.progress
retorna o tipo float, variando de 0 a 1. Indica o andamento do carregamento assíncrono, começando com 0 e finalizando com 1.
Obs.: Quando o valor da variável AsyncOperation .allowSceneActivation for falso, o valor deste parâmetro ficará preso em 0,9 no máximo até o valor da variável AsyncOperation .allowSceneActivation torna-se verdadeiro. Este valor do parâmetro se tornará 1

O tipo AsyncOperation object.isDone
retorna o tipo bool. Indica se o carregamento assíncrono foi concluído. O valor é verdadeiro se concluído, falso se não concluído.
Quando o valor do tipo AsyncOperation object.progress é 1, o valor desta variável é verdadeiro neste momento, mas isso ativará uma nova cena. Geralmente é difícil observar que o tipo AsyncOperation object.isDone é verdadeiro.

O tipo AsyncOperation object.priority
retorna o tipo int, usado para definir a prioridade de operações assíncronas.
Quando várias operações assíncronas são enfileiradas, a operação assíncrona com prioridade mais alta será executada primeiro. Mas se a operação assíncrona for iniciada em um thread em segundo plano, a alteração da prioridade não terá efeito.

AsyncOperation.completed
é um evento Action com um parâmetro AsyncOperation. O parâmetro AsyncOperation armazena as informações desse carregamento assíncrono.
Quando o carregamento assíncrono for concluído, ou seja, quando o valor do tipo AsyncOperation object.isDone for verdadeiro, este evento será executado uma vez.
 

Código LoadSceneManager

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.Events;

/// <summary>
/// 切换场景的管理器
/// </summary>
public class LoadSceneManager : SingletonPatternBase<LoadSceneManager>
{
    /// <summary>
    /// 重新切换当前场景
    /// </summary>
    public void LoadActiveScene()
    {
        SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
    }

    /// <summary>
    /// 切换到下一个场景,是否场景循环,最后一个场景切换是切换为第一个场景
    /// </summary>
    public void LoadNextScene(bool isCyclical=false)
    {
        int buildIndex = SceneManager.GetActiveScene().buildIndex + 1;

        //检测要切换的新场景的下标是否越界     这个参数的意思是BuildSettings中的场景总数
        if (buildIndex > SceneManager.sceneCountInBuildSettings-1)
        {
            if (isCyclical)
                buildIndex = 0;
            else
            {
                Debug.LogWarning($"加载场景失败!要加载的场景的索引是{buildIndex},越界了");
                return;
            }
        }

        SceneManager.LoadScene(buildIndex);
    }

    /// <summary>
    /// 加载上一个场景,包括可选择的场景循环功能
    /// </summary>
    public void LoadPreviousScene(bool isCyslical=false)
    {
        int buildIndex = SceneManager.GetActiveScene().buildIndex - 1;

        if (buildIndex < 0)
        {
            if (isCyslical)
            {
                buildIndex = SceneManager.sceneCountInBuildSettings - 1;
            }
            else
            {
                Debug.LogWarning($"加载场景失败!要加载的场景索引是{buildIndex},越界了!");
                return;
            }
        }

        SceneManager.LoadScene(buildIndex);
    }

    /// <summary>
    /// 异步加载场景  根据名字来切换场景
    /// </summary>
    public void LoadSceneAsync(string sceneName, UnityAction<float> loading = null,
        UnityAction<AsyncOperation> completed = null, bool setActiveAfterCompleted = true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        MonoManager.Instance.StartCoroutine(LoadSceneCoroutine(sceneName, loading, completed, setActiveAfterCompleted, mode));
    }

    IEnumerator LoadSceneCoroutine(string sceneName, UnityAction<float> loading = null,
        UnityAction<AsyncOperation> completed = null, bool setActiveAfterCompleted = true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        //开始加载资源
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneName, mode);

        asyncOperation.allowSceneActivation = false;  //资源加载最多到0.9

        //等待资源加载完毕
        while (asyncOperation.progress < 0.9f)
        {
            loading?.Invoke(asyncOperation.progress);
            yield return null;
        }

        //当asyncOperation.allowSceneActivation 为false,则asyncOperation.Progress最多只能到达0.9
        //我们人为把它们凑成1,可以方便外部进度条的显示
        loading?.Invoke(1);

        asyncOperation.allowSceneActivation = setActiveAfterCompleted;

        //加载资源完毕后执行的逻辑
        completed?.Invoke(asyncOperation);
    }

    /// <summary>
    /// 异步加载场景 根据索引来切换场景
    /// </summary>
    public void LoadSceneAsync(int sceneIndex,UnityAction<float>loading=null, 
        UnityAction completed = null,bool setActiveAfterCompleted=true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        MonoManager.Instance.StartCoroutine(LoadSceneCoroutine(sceneIndex,loading, completed,setActiveAfterCompleted, mode));
    }

    IEnumerator LoadSceneCoroutine(int sceneIndex, UnityAction<float> loading = null,
        UnityAction completed = null, bool setActiveAfterCompleted = true, LoadSceneMode mode = LoadSceneMode.Single)
    {
        //开始加载资源
        AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(sceneIndex, mode);

        asyncOperation.allowSceneActivation = false;  //资源加载最多到0.9

        //等待资源加载完毕
        while (asyncOperation.progress < 0.9f)
        {
            loading?.Invoke(asyncOperation.progress);
            yield return null;
        }

        //当asyncOperation.allowSceneActivation 为false,则asyncOperation.Progress最多只能到达0.9
        //我们人为把它们凑成1,可以方便外部进度条的显示
        loading?.Invoke(1);

        asyncOperation.allowSceneActivation = setActiveAfterCompleted;

        //加载资源完毕后执行的逻辑
        completed?.Invoke();
    }


}

roteiro de teste

[MenuItem("我的菜单/同步切换场景/重新切换到上一个场景")]
    static void Method3()
    {
        LoadSceneManager.Instance.LoadPreviousScene();
    }

    [MenuItem("我的菜单/异步切换场景/重新切换到场景1")]
    static void Method4()
    {
        LoadSceneManager.Instance.LoadSceneAsync("New Scene 1", (obj) =>
         {
             Debug.Log("加载进度是:" + obj * 100 + "%");
         }, (obj) =>
         {
             Debug.Log("加载完成了!");
         });
    }

Classe Unity Scene (classe de cena)

Objetos da classe Scene são usados ​​para armazenar informações da cena.

O tipo de cena object.buildIndex
retorna um tipo int, indicando o índice da cena na janela Build Settings.
Se a cena for inválida, o valor desta variável será -1.
Se a cena for carregada por meio do AssetBundle, o valor desta variável também será -1.

O tipo de cena object.isDirty
retorna o tipo bool, indicando se a cena foi modificada.
Quando modificamos uma cena no modo editor mas não a salvamos, o valor desta variável é verdadeiro. Depois que a cena for salva, o valor desta variável é falso

O tipo de cena object.isLoaded
retorna verdadeiro se a cena foi carregada. Se a cena não foi carregada ou não foi carregada, retorne falso

O tipo de cena object.name
retorna um tipo string, indicando o nome da cena. O final não contém o sufixo .unity,
que é seu nome na janela Projeto.
Nota: A cena deve ter sido carregada para que esta variável retorne corretamente o nome da cena. Se a cena não foi carregada ou não foi carregada, o valor retornado é “Null”

Cena object.path
retorna um tipo string, indicando o caminho da cena, com o sufixo .unity no final.
Por exemplo:
Assets/AssetBundleAssets/Scenes/TestScenes/Test.unity

O tipo de cena object.rootCount
retorna um tipo int, indicando o número total de componentes Transform em todos os objetos raiz do jogo na cena.

Tipo de cena object.GetRootGameObjects
retorna o tipo GameObject[], representando todos os objetos raiz do jogo na cena.
O objeto de jogo raiz oculto também será incluído, mas o objeto de jogo raiz de DontDestoryOnLoad não será incluído.

Tipo de cena object.IsValid
Se uma cena existe, é uma cena válida e o valor desta variável é verdadeiro.
Se uma cena não existe, é uma cena inválida e o valor desta variável é falso.
Nota: From EditorSceneManager.OpenScene O valor de IsValid da cena retornada é falso

O operador != pode ser usado entre dois objetos de cena.
Se as duas cenas forem diferentes, retorna verdadeiro, caso contrário, retorna falso.

O operador == pode ser usado entre dois objetos de cena.
Se as duas cenas forem iguais, retorna verdadeiro, caso contrário, retorna falso.

Classe Unity SceneManager (gerenciador de cena, usada para carregar cenas e alternar cenas)

Primeiro arraste as cenas que deseja saltar para as configurações de criação de arquivo

O namespace deve ser introduzido primeiro: usando UnityEngine.SceneManagement;

SceneManager.sceneCount
O número de cenas atualmente carregadas.

SceneManager.sceneCountInBuildSettings
O número de cenas que foram adicionadas à janela Configurações de construção.
Se você estiver no modo editor, a cena que foi aberta antes de entrar no modo de reprodução também será incluída. Se não for arrastada manualmente para a janela Build Settings, ela também será indexada na janela Build Settings, mas não podemos vê-la. Este índice é maior que o valor máximo visível de 1.

SceneManager.CreateScene(int scene name)
cria uma cena vazia, que será sobreposta à cena atual.
Se a cena criada tiver um nome duplicado, um erro será relatado.
O nome da cena pode ser visto na janela Hierarquia.
Se você deseja criar uma cena durante a edição, por exemplo, ao criar um script ou ferramenta de editor, você deve usar EditorSceneManager.NewScene

SceneManager.CreateScene(string nome da cena, CreateSceneParameters vários parâmetros para criar a cena)
cria uma cena vazia, que será sobreposta à cena atual.
Se a cena criada tiver um nome duplicado, um erro será relatado.
O nome da cena pode ser visto na janela Hierarquia.
Se você deseja criar uma cena durante a edição, por exemplo, ao criar um script ou ferramenta de editor, você deve usar EditorSceneManager.NewScene

SceneManager.GetActiveScene()
retorna um objeto Scene, representando informações sobre a cena atual.

SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
Use a sincronização para alternar para a cena atual novamente.

SceneManager.GetActiveScene().buildIndex+1 representa o índice da próxima cena na janela Build Settings.

Tipo de string SceneManager.GetActiveScene().name
. Indica o nome da cena atual. Pode ser usado com SceneManager.LoadScene para recarregar a cena atual

SceneManager.GetSceneAt(int index)
retorna informações sobre a cena no índice especificado na lista de cenas atualmente carregadas.
O índice deve ser maior ou igual a 0 e o mínimo é 0. Se for um número negativo ou o índice estiver fora dos limites, um erro será relatado.

SceneManager.GetSceneByBuildIndex (índice int da cena na janela Build Settings)
retorna as informações da cena nas Build Settings com base no índice passado.
A cena deve estar na janela Build Settings e atualmente carregada para que suas informações sejam retornadas. Caso contrário, um objeto Scene inválido será retornado.
O índice deve ser maior ou igual a 0 e o mínimo é 0. Se for um número negativo ou o índice estiver fora dos limites, um erro será relatado.

SceneManager.GetSceneByName(string scene name)
procura a cena com o nome de cena especificado na cena atualmente carregada.
Se encontrado, um objeto Scene é retornado, representando as informações desta cena. Se não for encontrado, um objeto Scene inválido será retornado.
O nome da cena pode ser a última parte do nome mostrado na janela Build Settings, caso em que a primeira informação de cena correspondente será retornada.
O nome da cena também pode ser o caminho exibido na janela Build Settings, caso em que as informações exatas da cena serão retornadas.
Os nomes das cenas não diferenciam maiúsculas de minúsculas.
Os nomes das cenas não devem conter a extensão .unity.

SceneManager.GetSceneByPath(string scene path)
encontra a cena com o caminho de recurso especificado na cena atualmente carregada.
Se encontrado, um objeto Scene é retornado, representando as informações desta cena. Se não for encontrado, um objeto Scene inválido será retornado.
O caminho para a cena deve ser relativo à pasta do projeto, por exemplo: "Assets/MyScenes/MyScene.unity"

SceneManager.LoadScene (índice int da cena na janela Build Settings, modo LoadSceneMode de carregar a cena);
        carrega de forma síncrona a cena no índice especificado.
        O primeiro parâmetro pode ser do tipo string, para que a cena especificada seja carregada com base no nome ou caminho da cena. Neste momento, a cena com este nome deve ser colocada na janela Build Settings com antecedência ou já foi carregada usando AssetBundle antes, para que este método seja eficaz. Se não houver nenhum, um erro será relatado. Nota: O nome da cena não contém o sufixo .unity. Além disso, os nomes das cenas não devem ter o mesmo nome. Se os nomes das cenas tiverem o mesmo nome, a primeira cena correspondente será carregada. Você pode usar o caminho da cena, por exemplo: Assets/AssetBundleAssets/Scenes/TestScenes/Scene1.unity.
        Se você usar LoadSceneMode.Single como segundo parâmetro, ele mudará automaticamente para a cena após o carregamento. A cena original será desinstalada. Isso é usado por padrão.
        Se LoadSceneMode.Additive for usado como segundo parâmetro, a cena será sobreposta à cena original após o carregamento. A cena original não será desinstalada e a cena ativa permanecerá a cena original.
        Usar este método para carregar uma cena não será carregado imediatamente, mas começará a ser carregado no próximo quadro. E como este método é síncrono, podem ocorrer atrasos. Recomenda-se usar o método LoadSceneAsync de carregamento assíncrono.

SceneManager.LoadSceneAsync (int o índice da cena na janela Build Settings, LoadSceneMode o modo de carregamento da cena);
        carrega assincronamente a cena no índice especificado.
        O primeiro parâmetro pode ser do tipo string, para que a cena especificada seja carregada com base no nome ou caminho da cena. Neste momento, a cena com este nome deve ser colocada na janela Build Settings com antecedência ou já foi carregada usando AssetBundle antes, para que este método seja eficaz. Se não houver nenhum, um erro será relatado. Nota: O nome da cena não contém o sufixo .unity. Além disso, os nomes das cenas não devem ter o mesmo nome. Se os nomes das cenas tiverem o mesmo nome, a primeira cena correspondente será carregada. Você pode usar o caminho da cena, por exemplo: Assets/AssetBundleAssets/Scenes/TestScenes/Scene1.unity.
        Se você usar LoadSceneMode.Single como segundo parâmetro, poderá alternar para a cena após o carregamento, e a cena original será descarregada. Isso é usado por padrão.
        Se LoadSceneMode.Additive for usado como segundo parâmetro, a cena poderá ser sobreposta à cena original após o carregamento. A cena original não será desinstalada e a cena ativa permanecerá a cena original.
        Usar este método para carregar uma cena não irá congelar o jogo. Geralmente é usado em conjunto com a barra de progresso na cena. Você pode controlar o progresso da barra de progresso enquanto carrega a cena.
        O tipo de valor de retorno deste método é do tipo AsyncOperation. Você pode avaliar se o carregamento assíncrono foi concluído com base no objeto deste tipo. Para obter detalhes, consulte a classe AsyncOperation.

SceneManager.MergeScenes(Cena cena 1, Cena cena 2)
transferirá todos os objetos do jogo na cena 1 para a cena 2, e a cena 1 será descarregada.
Geralmente, esse método pode ser usado somente quando LoadSceneMode.Additive é usado para carregar a cena.
Tanto a cena 1 quanto a cena 2 devem ser cenas carregadas.
Se a cena original 1 for a cena ativa, depois de desinstalada, a primeira cena no topo da janela Hierarquia se tornará a cena ativa.
Se a cena 1 original não for a cena ativa, a cena ativa não mudará após ser desinstalada.

SceneManager.MoveGameObjectToScene(GameObject o objeto do jogo a ser movido, a cena se move para a cena)
move um objeto do jogo da cena onde ele está localizado para a cena alvo.
Geralmente, esse método pode ser usado somente quando LoadSceneMode.Additive é usado para carregar a cena.
A cena para a qual você deseja mover deve ser uma cena carregada.
Se o objeto do jogo a ser movido for nulo, este método não terá efeito.
Se a cena para a qual você está movendo não foi carregada ou for uma cena inválida, um erro será relatado.

SceneManager.SetActiveScene(Scene scene name)
define a cena especificada como a cena ativa.

SceneManager.UnloadSceneAsync(índice de cena int na janela Configurações de compilação)
SceneManager.UnloadSceneAsync(string nome da cena ou caminho da cena)
SceneManager.UnloadSceneAsync(objeto de cena de cena)
SceneManager.UnloadSceneAsync(índice de cena int na janela Configurações de compilação, UnloadSceneOptions descarrega as opções de cena )
SceneManager.UnloadSceneAsync (string nome da cena ou caminho da cena, opções UnloadSceneOptions para descarregar a cena)
SceneManager.UnloadSceneAsync (objeto de cena da cena, opções UnloadSceneOptions para descarregar a cena)
Destrua a cena especificada e todos os objetos do jogo nesta cena.
Este método só é válido para cenas carregadas usando LoadSceneMode.Additive. Se houver apenas uma cena no jogo atual, este método será inválido e o console reportará um aviso amarelo.
Este método não descarregará os recursos da cena na memória. Se você quiser liberar os recursos, você deve chamar o método Resources.UnloadUnusedAssets depois de chamar este método. O tipo
do valor de retorno é o tipo AsyncOperation. Você pode usar este objeto para determinar se a operação assíncrona foi concluída.

Evento do tipo SceneManager.activeSceneChanged
UnityAction<Scene,Scene>.
Este evento será executado uma vez quando a cena ativa mudar.
O primeiro parâmetro representa a cena da atividade original e o segundo parâmetro representa a cena da atividade subsequente.

Evento do tipo SceneManager.sceneLoaded
UnityAction<Scene,LoadSceneMode>.
Este evento será executado toda vez que uma nova cena for carregada.
O primeiro parâmetro indica a nova cena a ser carregada, e o segundo parâmetro indica o modo de carregamento desta cena.


Evento do tipo SceneManager.sceneUnloaded UnityAction<Scene>.
Este evento será executado toda vez que uma cena for descarregada.
O parâmetro representa o objeto de cena descarregado.

Acho que você gosta

Origin blog.csdn.net/zaizai1007/article/details/132377762
Recomendado
Clasificación