Diferença entre o método Update e o FixedUpdate no Unity?


14

Estou começando a aprender o Unity3d e uma das confusões que recebo é a diferença entre Update()e FixedUpdate().

Estou seguindo o tutorial de desenvolvimento de jogos 2D do Lynda Unity, o instrutor usa o Updatemétodo, o jogador tem o componente RigidBody2D e o colisor de caixa, ele usa o Updatemétodo para traduzir o jogador, mas quando eu faço o mesmo no Updatejogador não se move, mas quando eu faço -lo em FixedUpdate, tudo funciona. Ele está dando um tutorial do Unity 4.3 e eu estou fazendo o curso no Unity 4.6.

Onde devo usar Updatee FixedUpdate?

Respostas:


14

Eu ia escrever isso como um comentário, mas acabou sendo bastante longo, então eu o transformei em uma resposta.

As respostas atuais são na maioria corretas, mas algumas coisas mencionadas são enganosas / erradas.

Em geral, a maioria das tarefas relacionadas ao jogo é executada Update.

Por exemplo, você não deseja pesquisar informações FixedUpdate(não por causa do desempenho, mas porque as chamadas simplesmente não funcionam corretamente). AI cai no mesmo barco.

Física atualizada continuamente é a única tarefa relacionada à jogabilidade que FixedUpdatedeve ser usada. Chamadas não contínuas / de vez em quando para coisas como Physics.Raycast, ou mesmo Rigidbody.AddForcepertencem Update. Minha menção Rigidbody.AddForceé aparentemente contrária ao que pode estar implícito na documentação, mas a chave é Contínua vs Não Contínua.

Uma enorme razão pela qual apenas a física contínua pertence FixedUpdateé a natureza real de FixedUpdate. Outras respostas mencionaram como FixedUpdate é chamado em um interval, but that's slightly misleading. In reality, a script is passed a time in Time.deltaTime/ fixo Time.fixedDeltaTimeque não corresponde diretamente ao tempo real entre as chamadas, mas ao tempo simulado entre as chamadas.

(* Time.deltaTimee Time.fixedDeltaTimetem o mesmo valor quando chamado em FixedUpdate[Unity é capaz de saber se a chamada atual se Time.deltaTimeoriginou durante FixedUpdatee retorna Time.fixedDeltaTime])

Naturalmente, o mesmo caminho Updatenão pode ser chamado de maneira constante por causa de desempenho variável, nem pode FixedUpdate. A principal diferença é que, cada quadro, se FixedUpdatenão tiver sido chamado com frequência suficiente para atingir o intervalo correto entre as chamadas, ele será chamado várias vezes (ou não será chamado a média é muito alta). É a isso que os documentos da Ordem de Execução se referem ao dizer que FixedUpdate pode ser chamado várias vezes por quadro:

... FixedUpdate: FixedUpdate é chamado frequentemente com mais freqüência que Update. Pode ser chamado várias vezes por quadro, se a taxa de quadros for baixa e não puder ser chamado entre quadros, se a taxa de quadros for alta ...

Isso não afeta a Física devido à natureza do restante da ordem de execução e do mecanismo, mas praticamente qualquer outra coisa que você colocar FixedUpdateserá afetada e causará problemas.

Por exemplo, se você colocar o processamento de AI dentro, FixedUpdatenão há razão para supor que o AI não pulará atualizações para vários quadros seguidos. Além disso, cada vez que o FixedUpdate fica para trás, sua IA é atualizada várias vezes em um único quadro antes que coisas como física e entrada / movimento do jogador sejam processadas, o que é, no mínimo, um desperdício de processamento, mas também é extremamente provável que cause para rastrear bugs e comportamento irregular.

Se você precisar fazer algo em um intervalo fixo, use outros métodos fornecidos pelo Unity, como Coroutinese InvokeRepeating.

E uma pequena nota sobre Time.deltaTimee quando usá-lo:

A maneira mais fácil de descrever o efeito de Time.deltaTime é alterar um número de unidade por quadro para unidade por segundo . Por exemplo, se você tiver um script com algo parecido transform.Translate(Vector3.up * 5)com o Update, estará movendo a transformação essencialmente a uma taxa de 5 metros por quadro . Isso significa que, se a taxa de quadros for baixa, o movimento será mais lento e se a taxa de quadros for alta, o movimento será mais rápido.

Se você pegar o mesmo código e alterá-lo para transform.Translate(Vector3.up * 5 * Time.deltaTime), o objeto está sendo movido a uma taxa de 5 metros por segundo . Isso significa que, independentemente da taxa de quadros, o objeto se moverá 5 metros a cada segundo (mas quanto mais lenta a taxa de quadros, mais saltado o movimento do objeto aparecerá, pois ele ainda move a mesma quantidade a cada X segundos)

Em geral, você deseja que seu movimento seja por segundo. Dessa maneira, independentemente da velocidade do computador, sua física / movimento se comportará da mesma maneira e você não terá bugs estranhos aparecendo em dispositivos mais lentos.

E não faz sentido usá-lo FixedUpdate. Por causa do que mencionei acima, você obterá o mesmo valor a cada chamada (o valor Timestep de atualização fixa) e isso não fará nada com seus valores. O movimento / física definido em FixedUpdatejá estará em unidades por segundo, para que você não precise dele.


4

A Updatefunção é chamada todos os quadros. Sua frequência depende da rapidez com que o computador é capaz de renderizar imagens. Em um computador mais lento, Updateé chamado com menos frequência do que em um computador mais rápido. Se você fizer cálculos com base no tempo, poderá normalizá-los usando o Time.deltaTimeque informa quanto tempo faz desde que a última vez Updatefoi chamada (ressalvas se aplicam).
Você geralmente usa Updatepara executar tarefas relacionadas à exibição (por exemplo, atualizar um elemento da interface do usuário)

A FixedUpdatefunção é chamada em intervalos fixos. Não importa com que frequência a imagem seja atualizada, FixedUpdateserá chamado de 1/Time.fixedDeltaTimevezes por segundo.
Você geralmente usa FixedUpdatepara executar tarefas relacionadas ao jogo (por exemplo, atualizar a física)


Essa é uma alternativa à multiplicação pelo tempo Time.delta? Existe um motivo para usar um ou outro?
1155 Ben Ben

@Bem eles têm dois objetivos diferentes e você deve usar a função correta para o que está fazendo.
o0 '.

@Lohoris Desculpe, eu quis dizer que existe um motivo para usar o FixedUpdate sobre Update e multiplicar as coisas por Time.deltaTime para torná-las independentes de quadros?
1155 Ben Ben

@ Ben sim, precisão. Em um sistema com renderização lenta, Updateé chamado cada vez menos e sua simulação sofrerá muito com isso. Você pode não perceber enquanto a simulação é simples, mas pode facilmente quebrar horrivelmente quando não é.
o0 '.

1
@ Ben não: se você deseja que sua simulação seja precisa, você deve executar vários pequenos passos, não grandes sempre que sejam maiores ou menores. E não, o ponto principal do FixedUpdate é que ele é chamado várias vezes, sem perguntas.
o0 '.

2

De: http://unity3d.com/learn/tutorials/modules/beginner/scripting/update-and-fixedupdate

O tempo usado no FixedUpdate não é variável.

Se o seu jogo começar a ficar lento, quando ele chegar, você não quer> 10segundos de física em uma atualização; portanto, isso geralmente é feito no FixedUpdate, que é chamado em um intervalo fixo.

Por exemplo:

Update(float elapsedSeconds)
{
  Position += Velocity * 34.23423; //Windows Update is self-important
}
FixedUpdate(float elapsedSeconds)
{
  Position += Velocity * 0.0166; //60fps
}

Onde:

Update(34.23423)

==

FixedUpdate(10.0)
FixedUpdate(10.0)
FixedUpdate(10.0)
//4.23423 + 5.76577 game-seconds later...
FixedUpdate(10.0)

Eu mencionei isso na minha resposta, mas FixedUpdatena verdade não é chamado em um intervalo fixo. A natureza real FixedUpdateé apertar vários ciclos de física em um quadro se o jogo começar a atrasar e pular os ciclos se estiver indo rápido demais, para que a média funcione no Timestep de atualização fixa. O Unity não é multiencadeado, portanto, não há como garantir chamadas FixedUpdate em um intervalo fixo (o que acontece quando um FixedUpdate leva muito tempo). Mesmo que fosse, provavelmente ainda seria quase impossível.
Selali Adobor

A maioria das pessoas do [Unity?] Não sabe que Render / Update / FixedUpdate são todos invocados em um único método de retorno de chamada, então eu conceituei. Obrigado pelo seu esforço!
Jon

2

Updateé chamado o mais rápido possível. A variável 'Time.deltaTime' é definida como a quantidade real de tempo que passou desde a última chamada. Se o atraso ou algo semelhante atrasar o jogo, Updateainda será chamado apenas uma vez depois que o atraso terminar, com um valor alto de deltaTime.

FixedUpdateé chamado em intervalos regulares. Ele nunca será chamado com mais frequência do que a proporção especificada em 'Time.fixedDeltaTime'. Se o atraso ou algo semelhante atrasar o jogo, FixedUpdateele será chamado várias vezes em rápida sucessão para permitir que o jogo o recupere. Time.deltaTimeé definido como igual a Time.fixedDeltaTimeantes da FixedUpdateexecução, mas isso é apenas uma farsa para facilitar a migração do código entre os dois.

Geralmente, Updatedeve ser usado para comportamentos interpoláveis ​​e FixedUpdatepara comportamentos que devem ser calculados passo a passo ou que dependam daqueles que o fazem, como o movimento baseado na física. Se você estiver escrevendo algum tipo de loop ao Updatelongo das linhas for(time=0;time<=deltaTime;time+=someStep)..., provavelmente deverá fazê-lo no FixedUpdate.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.