Unity: Update Versus FixedUpdate

Yet another article on when to use the Update and Fixedupdate methods.

TD;LR: Ter, facilmente, recriado o problema de misturar e combinar timesteps, eu me convenci de que eu deveria colocar todo o estado do jogo em FixedUpdate métodos.antes de entrar na substância deste artigo, queria esclarecer por que estou interessado na unidade em primeiro lugar:

  • eu NÃO tenho muito interesse em jogar ou criar jogos de vídeo
  • eu tenho um interesse em construir ferramentas úteis (foi um desenvolvedor web por MUITOS anos)
  • eu NÃO sou um early adopter
  • a Unidade é um BEM ESTABELECIDO solução para criar multi-plataforma de experiências em 3D

Com tudo isso em mente, a construção de práticas web movido a Realidade Aumentada (AR) soluções com a Unidade é algo que eu preciso aprender.quanto à unidade de aprendizagem, não achei particularmente úteis os tutoriais oficiais de unidade. Eu encontrei o curso Udemy aprender Unity 3D para principiantes absolutos para ser excelente.

I was cruising through the materials and found myself hung up on the lesson Difference between Update and FixedUpdate. Pesquisando um pouco mais, o cerne do problema era que eu não entendia a seguinte lógica.

Update (); … usado para actualizações regulares tais como: mover objectos não físicos

FixedUpdate();… usado para actualizações regulares tais como:: Ajustando objetos de Física (Rigidbody)

Unity — Update and FixedUpdate — Unity tutoriais oficiais

um pouco mais de pesquisa apareceu:

Em conclusão, coloque toda a sua lógica de jogo em qualquer atualização ou atualização. Não misture e combine tempesteps a menos que você esteja disposto a morder a bala e aceitar um pouco de gaguez. Além disso, vale a pena considerar colocar todo o estado do jogo em FixedUpdate, usando Update exclusivamente para entrada do Usuário, efeitos visuais e interpolação entre estados do jogo. Enquanto isso requer uma mudança na forma como você Estrutura seus jogos, é uma estrutura de design comprovada com muitas vantagens.

— KinematicSoup — Timesteps and Acheiving Smooth Motion in Unity

um clipe de vídeo no artigo ilustra o problema da mistura e correspondência de tempesteps.

Antes de seguir este conselho que eu queria para recriar o problema de misturar e combinar timesteps no meu próprio.

a versão final do projeto que eu usei por escrito este artigo está disponível para download.

Update Versus FixedUpdate

precisamos começar com um entendimento básico da diferença entre os métodos de atualização e FixedUpdate. Para ilustrar, criamos um GameObject vazio chamado Setup e adicionamos o seguinte componente de script:

Assets / Setup.cs (incompleto)

a nossa saída da consola após 3 segundos parecia:

Observações:

  • Update é chamado antes de cada revestimento; a freqüência (taxa de quadros) que varia de acordo com a complexidade da prestação de host e o dispositivo. Computadores poderosos podem alcançar taxas de quadros superiores a 150fps; Meu Computador de desenvolvimento estava rodando cerca de 50fps. Abaixo de 30 fps, é considerada uma experiência pobre.
  • FixedUpdate is called before each internal physics update (moving things due to physics, e.g., gravity). Unity ‘ s fixed timestep defaults to 0.02; leads to FixedUpdate being called 50 times per second.

simula a taxa de quadros lenta

A fim de simular uma taxa de quadros lenta (10fps), actualizamos a configuração.script cs:

ativos/configuração.cs (incompleto)

a nossa saída da consola após 3 segundos parecia:

Observações:

  • Configuração vSyncCount para 0 desativa a Unidade de sincronização processa e atualização de tela taxas.
  • a taxa de quadros real pode ser menor que o TARGET_FRAME_RATE devido às limitações do dispositivo hospedeiro e à complexidade da renderização.

animação Manual

A fim de observar o efeito de várias animações, começamos por colocar um cubo fixo para referência.

We add our first animated GameObject (Sphere) in front of it with the following script component.

Assets/Sphere.cs (incomplete)

Running it with the normal frame rate:

Running it with 10fps frame rate:

Observations:obviamente, temos um problema. Não queremos que a velocidade de animação seja dependente da taxa de quadros.

  • o problema é porque estamos configurando a velocidade para ser 0.1 unidades / quadro; queremos que a velocidade seja medida em unidades / segundo.
  • a solução é fornecer a velocidade nas unidades de unidades / segundo; 0.1 unidades / quadro * 50 quadros / segundo = 5 unidades / segundo. Então usamos o tempo.deltaTime para saber o tempo desde a última chamada para atualizar. Então a distância percorrida é Velocidade * deltaTime.activos/esfera.cs (incompleto)

    com esta correção no lugar, temos a mesma animação independentemente da taxa de quadros (mas com 10fps, é carne seca como esperado).

    depois de Ter usado a reduzida taxa de quadros para ilustrar a necessidade de fornecer velocidade em unidades / segundo, nós podemos comentar as linhas de Configuração.cs que simulou uma taxa de quadros lenta.

    animação em física

    em vez de animar manualmente um GameObject, podemos animá-lo aplicando-lhe física. Podemos animar um cilindro (mover para a direita 5 unidades / segundo):

    • Criação de um Plano (chamado Plano)
    • Criação de um Cilindro (chamado de Cilindro)
    • Adicione um Rigidbody componente do Cilindro (e congelamento a rotação em todas as direções)
    • Criar uma física do material, Escorregadio, sem o atrito e aplicá-lo tanto para o Cilindro e o Plano
    • Inicie o Cilindro, com uma velocidade inicial usando um componente de script

    Assets/Cilindro.cs

    com isto no lugar, podemos ver que a esfera e cilindro se movem para a direita na mesma velocidade.

    Observações:

    • A Esfera da posição é atualizada imediatamente antes da renderização (manualmente no método Update)
    • O Cilindro, a posição é atualizada no interno física de atualização.

    Animation with Animation

    uma terceira maneira de animar um GameObject é com uma animação (obviamente). Nós podemos animar uma cápsula (tentando mover para a direita por 5 unidades / segundo) por:

    • criando uma cápsula (chamada cápsula)
    • Criando um controlador de animação (também cápsula) e adicionando como um componente para o GameObject cápsula.
    • criando uma animação (também cápsula).
    • no controlador de animação criar um estado (Start) com o seu movimento para ser a animação da cápsula.finalmente, animamos a posição para que a posição horizontal da cápsula seja de 5 unidades em 1 segundo.com isso no lugar, podemos ver que a esfera, cilindro, cápsula (quase) se move para a direita na mesma velocidade.

      Observações:

      • Não sei por que, mas a Cápsula movido ligeiramente mais rápido do que o esperado; problemas de tiro por um tempo, para não descobrir o porquê.
      • A Posição da cápsula pode ser configurada para atualização antes da renderização (padrão) ou durante a atualização física.

      implicação de uma taxa de quadros rápida

      em computadores potentes, pode-se alcançar taxas de quadros até 150fps. Nestes computadores com as atualizações de física padrão 50 vezes por segundo (0,02 segundos entre Atualizações), os elementos que são atualizados Antes de cada renderização são atualizados mais frequentemente do que aqueles atualizados nas atualizações de física. Esta discrepância é a fonte do problema de misturar e combinar temperos.embora não possa aumentar a taxa de quadros da minha máquina de desenvolvimento (limitada a cerca de 50 PPS), posso desacelerar artificialmente as actualizações de física para 10 actualizações por segundo (0.1 segundos entre as actualizações) usando a configuração do projecto.

      Como você pode ver, misturando e combinando timesteps podemos ter recriado o problema (inconsistente movimento entre GameElements).

      para corrigir, podemos alterar a animação da cápsula para atualizar as atualizações de física, e também atualizar o componente de script da esfera como segue:

      ativos/esfera.cs

      com isso, todas as animações são consistentemente atualizadas antes de cada atualização física.

      Finalmente, voltamos a nossa física de atualização para ser 50fps (ou a cada 0,02 segundos); alcançar consistentes e atualizações pontuais.

      Conclusões

      Ter, facilmente, recriado o problema de misturar e combinar timesteps, eu me convenci de que eu deveria colocar todo o estado do jogo em FixedUpdate métodos.

    Deixe uma resposta

    O seu endereço de email não será publicado.