[#TeamUnity] Duda sobre Time.deltaTime y FPS muy bajos

Asnarth

Buenas, me ha dado por tontear en Unity y estoy haciendo un juego (por decir algo) 2D con una movilidad parecida a la de Mario Galaxy (pequeños planetas que te atraen pero puedes moverte por la superficie).

Para el movimiento que busco me resulta un poco feo utilizar Rigidbody, así que estoy codificando el movimiento directamente seteando transform.position. No me está quedando del todo mal, y más o menos va saliendo lo que quiero, pero dándole una vueltas me ha venido una idea a la cabeza y no sé exactamente cómo afrontarla.

He leído que prácticamente siempre viene bien utilizar Time.deltaTime al tratar con movimientos, para evitar que la velocidad sea dependiente del framerate al que se mueva el juego. Hasta ahí todo correcto, pero la duda que me asalta viene al pensar en posibles ocasiones de caída del framerrate.

Si mi juego se estuviera ejecutando en una tostadora, y por algún motivo la tasa de frames bajara a menos de 1FPS, Time.deltaTime pasaría a ser más de 1, por lo que la velocidad de movimiento se estaría multiplicando por esa cantidad. Supongamos que mi velocidad de movimiento base es 10f, y normalmente la multiplico por valores en torno 0.02f, por lo que cada frame me estaría moviendo en torno a 0.02 unidades. Si de pronto ocurre una bajada a 0.5FPS, la velocidad de ese frame sería 10*2 = 20 unidades.

Aplicado a mi ejemplo, ese salto en la velocidad podría conllevar que en lugar de desplazarme por la superficie del planeta, ocurriera un salto que me sacara del radio de atracción, por lo que quedaría vagando en el espacio. Olvidando mi ejemplo, esto podría suponer que el personaje atraviese paredes que en un principio no debería poder atravesar.

¿Cómo se podría afrontar esto? He preguntado en el hilo de la taberna, y alguien me ha mencionado el FixedUpdate, pero no sé cómo entraría aquí, ya que el movimiento lo estoy realizando en el Update, ¿quizá debería cambiarlo?

Otra opción que se me ha ocurrido es la posibilidad de pasar a utilizar un valor fijo para Time.deltaTime sólo si el framerate cae por debajo de un valor definido, pero no sé hasta que punto esto podría ser buena práctica (que me da que no).

Al final me ha quedado una buena biblia, pero bueno, muchas gracias de antemano.

RPV: Si los FPS bajan de más (< 1FPS), y la velocidad se está multiplicando por Time.deltaTime, la velocidad en ese frame podría ser tan grande que el objeto que se mueve atraviese paredes. ¿Cómo se soluciona esto?

totespare

Me lo pongo en favs y en cuanto pueda intento pensar en algunas cosillas para que pruebes. De primeras lo que puedo decirte es que si ese supuesto nunca se va a dar, no pierdas mucho tiempo en ello. Si es principalmente cuestión de curiosidad y demás, entonces chachi. Sin pensar mucho, pégale una googleada a cómo lo hacen algunos juegos online, por ejemplo de carreras, para sincronizar las entidades entre el cliente y el servidor, ya que los métodos que usarán seguramente sean parecidos a lo que buscas, como comprobaciones de que las posiciones del coche sean válidas en cada tick, cómo corrigen esas posiciones etc., que suelen producirse por problemas en la conexión y demás.

Asnarth

Es más curiosidad que otra cosa, pero sí que tengo el "miedo" ahí de cuando tenía un pc muy mierdero y juegos tipo The Binding of Isaac llegaba un momento en el que bajaban a 10 fps.

Cuando salga del curro le echo un ojo a lo que has dicho, a ver si encontrara algo. Gracias por la respuesta.

kesada7

Respuesta corta, usa rigibody y las físicas de unity xD

No en serio, por que dices que te parece feo usarlo para lo que comentas? Es que lo que tu quieres hacer para que funcione no es tan sencillo como setear posiciones del transform, te tienes que montar tu propio sistema de físicas y que hagan cosas como por ejemplo en este caso interpolación de movimiento y detectar si colisionarías con una pared. Intento explicartelo con mis skills de paint:

Marron: Suelo y paredes con collisiones
Verde: El movimiento de tu jugador que como ves en el supuesto caso que tu dices de muy bajos fps la velocidad sería tan alta que en ese tick se saltaría la pared y la atravesaría.
Azul: Interpolación de movimiento: Se detecta que entre medias del movimiento ha habido una colision y el player se quedaría en la última posición azul sin atravesar la pared.

Esta es la respuesta larga para decirte lo mismo xD que uses el sistema de físicas de unity que te solventa estos y más problema que para eso están xD Al no se que quieras aprender a montarte tu propio motor pero entonces deja unity y te montas tu propio sistema de colisiones y todo en c++ con SFML

1 1 respuesta
Asnarth

#4 Supongo que, según lo que dices, por muy bajos que sean los FPS, al utilizar un Rigidbody ¿el propio motor tienen en cuenta estos casos y detectaría la colisión?

De todas formas, eso funcionaría en el ejemplo de la pared, pero concretamente yo no tengo una colisión en sí, sino que el al ocurrir tanto desplazamiento de golpe, me saldría de unos límites de los que no podría salirme si los FPS ocurrieran a una velocidad normal (debido a que el movimiento es circular, pero al saltar tanto en la cordenada X, dejaría de moverme correctamente en la Y).

Usuarios habituales

  • Asnarth
  • kesada7
  • totespare

Tags