¿Diferencia entre el método de actualización y FixedUpdate en Unity?

14

Estoy empezando a aprender Unity3d y una de las confusiones que obtengo es la diferencia entre Update()y FixedUpdate().

Estoy siguiendo el tutorial de desarrollo de juegos 2D de Lynda Unity allí, el instructor usa el Updatemétodo, el jugador tiene el componente RigidBody2D y el colisionador de cajas, usa el Updatemétodo para traducir al jugador, pero cuando hago lo mismo, Updateel jugador no se mueve, pero cuando lo hago adentro FixedUpdate, todo funciona. Él está dando un tutorial de Unity 4.3 y estoy tomando el curso en Unity 4.6.

¿Dónde debo usar Updatey FixedUpdate?

monje
fuente

Respuestas:

14

Iba a escribir esto como un comentario, pero terminó siendo bastante largo, así que lo convertí en una respuesta.

Las respuestas actuales son en su mayoría correctas, pero algunas cosas mencionadas son engañosas / incorrectas.

En general, la mayoría de las tareas relacionadas con el juego entrarán Update.

Por ejemplo, no desea sondear la entrada FixedUpdate(no por el rendimiento, sino porque las llamadas simplemente no funcionarán correctamente). La IA cae en el mismo bote.

La física actualizada continuamente es la única tarea relacionada con el juego que se FixedUpdatedebe utilizar. Llamadas no continuas / de vez en cuando a cosas como Physics.Raycast, o incluso Rigidbody.AddForcepertenecer Update. Mi mención de Rigidbody.AddForcees aparentemente contraria a lo que podría implicar la documentación, pero la clave es Continua vs No continua.

Una gran razón por la que solo pertenece la física continua FixedUpdatees la naturaleza real de FixedUpdate. Otras respuestas han mencionado cómo se llama a FixedUpdate en un interval, but that's slightly misleading. In reality, a script is passed a time in Time.deltaTime/ Time.fixedDeltaTime* fijo que no corresponde directamente al tiempo real entre llamadas, sino al tiempo simulado entre llamadas.

(* Time.deltaTimey Time.fixedDeltaTimeson el mismo valor cuando se llama FixedUpdate[Unity puede decir si la llamada actual se Time.deltaTimeoriginó durante FixedUpdatey regresa Time.fixedDeltaTime])

Naturalmente, Updateno se puede llamar de la misma manera de manera constante debido al rendimiento variable, tampoco se puede FixedUpdate. La diferencia clave es que cada cuadro, si FixedUpdateno se ha llamado con la frecuencia suficiente para promediar el intervalo correcto entre llamadas, se llama varias veces (o no se llama, el promedio es demasiado alto). Esto es a lo que se refieren los documentos sobre la orden de ejecución al decir que FixedUpdate se puede llamar varias veces por marco:

... FixedUpdate: FixedUpdate a menudo se llama con más frecuencia que Update. Se puede llamar varias veces por fotograma, si la velocidad de fotogramas es baja y no se puede llamar entre fotogramas si la velocidad de fotogramas es alta ...

Esto no afecta a la Física debido a la naturaleza del resto de la orden de ejecución y el motor, pero casi cualquier otra cosa que ingrese FixedUpdatese verá afectada y causará problemas.

Por ejemplo, si coloca el procesamiento de AI dentro, FixedUpdateno hay razón para suponer que la IA no omitirá las actualizaciones para varios cuadros seguidos. Además, cada vez que `FixedUpdate se queda atrás, su IA se actualizará varias veces en un solo cuadro antes de que se procesen cosas como la física y la entrada / movimiento del jugador, lo que es un desperdicio de procesamiento como mínimo, pero también es extremadamente probable que cause problemas rastrear errores y comportamientos erráticos.

Si necesita hacer algo en un intervalo fijo, use otros métodos que proporciona Unity, como Coroutinesy InvokeRepeating.

Y una pequeña nota sobre Time.deltaTimey cuándo usarlo:

La forma más fácil de describir el efecto de Time.deltaTime es que cambia un número de unidad por cuadro a unidad por segundo . Por ejemplo, si tiene un script con algo como transform.Translate(Vector3.up * 5)en Actualización, esencialmente está moviendo la transformación a una velocidad de 5 metros por cuadro . Eso significa que si la velocidad de fotogramas es baja, el movimiento es más lento, y si la velocidad de fotogramas es alta, el movimiento es más rápido.

Si toma el mismo código y lo cambia transform.Translate(Vector3.up * 5 * Time.deltaTime), el objeto se está moviendo a una velocidad de 5 metros por segundo . Eso significa que no importa la velocidad de fotogramas, el objeto se moverá 5 metros por segundo (pero cuanto más lenta sea la velocidad de fotogramas, más rápido aparecerá el movimiento del objeto ya que todavía se mueve la misma cantidad cada X segundos)

En general, quieres que tu movimiento sea por segundo. De esa manera, no importa a qué velocidad vaya la computadora, su física / movimiento se comportará de la misma manera, y no tendrá errores extraños apareciendo en dispositivos más lentos.

Y no tiene sentido usarlo FixedUpdate. Debido a lo que mencioné anteriormente, obtendrá el mismo valor en cada llamada (el valor de Tiempos de actualización fijos), y no hará nada a sus valores. El movimiento / física definido en FixedUpdateya estará en unidades por segundo, por lo que no lo necesita.

Selali Adobor
fuente
4

La Updatefunción se llama cada cuadro. Su frecuencia depende de qué tan rápido la computadora sea capaz de renderizar imágenes. En una computadora más lenta, Updatese llama con menos frecuencia que en una más rápida. Si hace cálculos basados ​​en el tiempo, puede normalizarlos usando lo Time.deltaTimeque le dice cuánto tiempo ha pasado desde la última vez que Updatese llamó (se aplican las advertencias).
Generalmente lo utilizará Updatepara realizar tareas relacionadas con la visualización (por ejemplo, actualizar un elemento de la interfaz de usuario)

La FixedUpdatefunción se llama a intervalos fijos. Independientemente de la frecuencia con la que se actualice la imagen, FixedUpdatese llamarán 1/Time.fixedDeltaTimeveces por segundo
. Generalmente se utilizará FixedUpdatepara realizar tareas relacionadas con el juego (por ejemplo, actualizar la física)

3Dbloblones
fuente
¿Es esta una alternativa a multiplicar por tiempo Time.delta? ¿Hay alguna razón para usar uno u otro?
Ben
@Ben tienen dos objetivos diferentes y debes usar la función correcta para lo que estás haciendo.
o0 '.
@Lohoris Lo siento, quiero decir, ¿hay alguna razón para usar FixedUpdate sobre Update y multiplicar las cosas por Time.deltaTime para que sean independientes del marco?
Ben
@Ben sí, precisión. En un sistema con representación lenta, Updatese llama cada vez con menos frecuencia, y su simulación sufrirá mucho por eso. Es posible que no lo note mientras la simulación es simple, pero se romperá fácilmente cuando no lo sea.
o0 '.
1
@Ben no: si quieres que tu simulación sea precisa, debes tomar muchos pasos pequeños, no enormes al azar cada vez más grandes o más pequeños. Y no, el objetivo de FixedUpdate es que se llama así muchas veces, sin hacer preguntas.
o0 '.
2

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

El paso de tiempo utilizado en FixedUpdate no es variable.

Si su juego comienza a retrasarse, cuando se pone al día, no desea más de 10 segundos de física en una actualización, por lo que generalmente se realiza en FixedUpdate, que se llama en un intervalo fijo.

Por ejemplo:

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

Dónde:

Update(34.23423)

==

FixedUpdate(10.0)
FixedUpdate(10.0)
FixedUpdate(10.0)
//4.23423 + 5.76577 game-seconds later...
FixedUpdate(10.0)
Jon
fuente
Mencioné esto en mi respuesta, pero en FixedUpdaterealidad no se llama en un intervalo fijo. La naturaleza real de FixedUpdatees exprimir múltiples ciclos de física en un solo cuadro si su juego comienza a retrasarse y omitir ciclos si va demasiado rápido para que el promedio funcione en el Paso de tiempo de actualización fijo. La unidad no es multiproceso, por lo que no habría forma de garantizar las llamadas de FixedUpdate en un intervalo fijo (lo que sucede cuando un FixedUpdate tarda demasiado). Incluso si lo fuera, probablemente todavía sería casi imposible.
Selali Adobor
La mayoría de las personas [¿Unidad?] No son conscientes de que Render / Update / FixedUpdate se invocan desde un único método de devolución de llamada, así que conceptualicé. ¡Gracias por tu esfuerzo!
Jon
2

Updatese llama lo más rápido posible. La variable 'Time.deltaTime' se establece en la cantidad de tiempo real que pasó desde la última llamada. Si el retraso o algo similar ralentiza el juego, Updatese seguirá llamando solo una vez que el retraso haya finalizado, con un alto valor de deltaTime.

FixedUpdatese llama a intervalos regulares. Nunca se llamará con más frecuencia que la proporción especificada en 'Time.fixedDeltaTime'. Si el retraso o algo similar ralentiza el juego, FixedUpdatese llamará varias veces en una sucesión rápida para permitir que el juego se ponga al día. Time.deltaTimese establece igual que Time.fixedDeltaTimeantes de FixedUpdateejecutarse, pero esto es solo una falsificación para facilitar la migración de código entre los dos.

En general, Updatedebe usarse para comportamientos interpolables y FixedUpdatepara comportamientos que deben calcularse paso a paso, o que dependen de aquellos que lo hacen, como el movimiento basado en la física. Si está escribiendo algún tipo de bucle a lo Updatelargo de las líneas, for(time=0;time<=deltaTime;time+=someStep)...entonces probablemente debería hacerlo en FixedUpdate.

Mark Green
fuente