Código e princípio de carregamento assíncrono suave e suave

Este artigo é mais detalhado. Endereço de reimpressão: https://gameinstitute.qq.com/community/detail/125245
Background

Normalmente a cena principal do jogo contém mais recursos, o que levará a um tempo maior para carregar a cena. Para evitar esse problema, você pode carregar primeiro a cena de carregamento e, em seguida, carregar a cena principal por meio da cena de carregamento. Como a cena de carregamento contém menos recursos, a velocidade de carregamento é rápida. Ao carregar a cena principal, uma barra de progresso geralmente é exibida na interface de carregamento para informar ao jogador sobre o progresso atual do carregamento. No Unity, a cena do jogo pode ser carregada de forma assíncrona chamando a função Application.LoadLevelAsync, e o progresso do carregamento da cena pode ser obtido consultando o valor de AsyncOperation.progress.

tentar - encontrar problemas

Na primeira etapa, após carregar a cena de carregamento, chame a seguinte função LoadGame para iniciar o carregamento da cena do jogo, use o carregamento assíncrono para carregar a cena 1 (a cena de carregamento é 0, a cena principal é 1), por meio do mecanismo Coroutine fornecido pelo Unity, podemos chamar convenientemente a função SetLoadingPercentage após cada quadro para atualizar o valor da barra de progresso exibida na interface.

public void LoadGame() {
    StartCoroutine(StartLoading_1(1));
private IEnumerator StartLoading_1(int scene) {
    AsyncOperation op = Application.LoadLevelAsync(scene);
    while(!op.isDone) {            
        SetLoadingPercentage(op.progress * 100);
        yield return new WaitForEndOfFrame();
    }        

O efeito da barra de progresso final é mostrado a seguir:
Unity carregando o problema suave do controle deslizante da barra de progresso da cena de carregamento

A barra de progresso não exibe continuamente o progresso do carregamento, mas faz uma pausa para alternar um número, depois uma pausa para alternar um número e, finalmente, alterna para a cena principal sem mostrar 100%. A razão é que Application.LoadLevelAsync não é um carregamento em segundo plano real. Ele carrega alguns recursos do jogo a cada quadro e fornece um valor de progresso, então o jogo ainda irá congelar durante o carregamento, e o valor de AsyncOperation.progress não é suficiente. preciso. Quando a cena principal for carregada, o Unity alternará automaticamente a cena, portanto, o código no loop while no código acima não será chamado, resultando na barra de progresso não mostrando 100%.

Reparação - 100% concluída

Para fazer a barra de progresso exibir 100%, uma maneira complicada é multiplicar o valor de AsyncOperation.progress por 2, para que quando o carregamento chegar a 50%, a interface exiba 100%. A desvantagem é que quando 100% é exibido na interface, o usuário terá que esperar um pouco antes de entrar no jogo. Na verdade, o Unity fornece um método para alternar cenas manualmente. Definir AsyncOperation.allowSceneActivation como false pode proibir o Unity de alternar cenas automaticamente após o carregamento. O código StartLoading_2 modificado é o seguinte:

// this function is not work
private IEnumerator StartLoading_2(int scene) {
    AsyncOperation op = Application.LoadLevelAsync(scene);
    op.allowSceneActivation = false;
    while(!op.isDone) {
        SetLoadingPercentage(op.progress * 100);
        yield return new WaitForEndOfFrame();
    }
    op.allowSceneActivation = true;   

Primeiro definimos AsyncOperation.allowSceneActivation como false e, em seguida, definimos como true quando o carregamento é concluído. O código parece correto, mas o resultado da execução é que a barra de progresso ficará em 90% no final e a cena não mudará. Ao imprimir o log, verifica-se que AsyncOperation.isDone é sempre falso, e o valor de AsyncOperation.progress permanece inalterado após aumentar para 0,9, o que significa que a cena nunca será carregada.
O Unity carrega o problema suave do controle deslizante da barra de progresso da cena de carregamento

Encontrei a resposta neste post. Acontece que, depois de definir allowSceneActivation como false, o Unity carregará apenas a cena em 90% e os 10% restantes não serão carregados até que allowSceneActivation seja definido como true. Isso deve ser dito para ser um poço. Portanto, o código é alterado para o seguinte. Quando AsyncOperation.progress atingir 0,9, atualize diretamente o valor da barra de progresso para 100% e defina AsyncOperation.allowSceneActivation como true para permitir que o Unity continue a carregar cenas inacabadas.

private IEnumerator StartLoading_3(int scene) {
    AsyncOperation op = Application.LoadLevelAsync(scene);
    op.allowSceneActivation = false;
    while(op.progress < 0.9f) {
        SetLoadingPercentage(op.progress * 100);
        yield return new WaitForEndOfFrame();
    }
    SetLoadingPercentage(100);
    yield return new WaitForEndOfFrame();
    op.allowSceneActivation = true;   

O efeito final é o seguinte:
o Unity carrega o problema suave do controle deslizante da barra de progresso da cena de carregamento

Grind - adicionar animação

Embora a barra de progresso acima resolva o problema de exibição de 100%, ela não parece natural e bonita porque a atualização do valor da barra de progresso não é contínua. Para parecer que está carregando continuamente, você pode inserir um valor de transição toda vez que a barra de progresso for atualizada. A estratégia que adoto aqui não é atualizar o valor da barra de progresso imediatamente após obter o valor de AsyncOperation.progress, mas somar 1 ao valor original para cada quadro, de modo que seja gerado o efeito de animação dos números rolando continuamente .Thunder Este método é usado para exibir o progresso do download em .

private IEnumerator StartLoading_4(int scene) {
    int displayProgress = 0;
    int toProgress = 0;
    AsyncOperation op = Application.LoadLevelAsync(scene);
    op.allowSceneActivation = false;
    while(op.progress < 0.9f) {
 toProgress = (int)op.progress * 100;
        while(displayProgress < toProgress) {
            ++displayProgress;
            SetLoadingPercentage(displayProgress);
            yield return new WaitForEndOfFrame();
        }
    }
    toProgress = 100;
    while(displayProgress < toProgress){
 ++displayProgress;
        SetLoadingPercentage(displayProgress);
        yield return new WaitForEndOfFrame();
    }
    op.allowSceneActivation = true;

displayProgress é usado para registrar o valor a ser exibido na barra de progresso. A animação da barra de progresso final é a seguinte:
Unity carregando o problema suave do slider da barra de progresso da cena de carregamento

Comparado com o primeiro tipo de barra de progresso
Carregamento da unidade Problema suave do controle deslizante da barra de progresso da cena de carregamento

Resumir

Se você precisar analisar tabelas de dados, gerar pools de objetos e executar conexões de rede e outras operações antes de carregar a cena principal do jogo, poderá atribuir um peso a essas operações e usá-los para calcular o progresso do carregamento. Se sua cena carregar muito rapidamente, você pode usar uma barra de progresso falsa para permitir que o jogador observe a animação de carregamento por alguns segundos antes de carregar a cena. Resumindo, embora a barra de progresso seja pequena, não é fácil fazer bem.
link original

Os direitos autorais pertencem ao autor. Para reimpressão comercial, entre em contato com o autor para obter autorização. Para reimpressão não comercial, indique a fonte

Acho que você gosta

Origin blog.csdn.net/Kevin_meta/article/details/127438345
Recomendado
Clasificación