lunes, 23 de marzo de 2015

Salto incremental con el controlador de Unity 5

Con el movimiento del personaje ya conseguido me faltaba mejorar algunas cosas, por ejemplo hacer el salto incremental, que cuanto más tiempo dejemos pulsado el botón de salto más alto salte. Algo sencillo en principio, además que ya lo tenía hecho en el controlador viejo, pero las cosas a veces se complican.


La idea básica es dar un impulso inicial al salto cuando se presiona el botón y en cada frame ir aumentando un poco ese impulso si el botón sigue pulsado hasta un tiempo máximo de pulsación del salto. En peras y manzanas: Si pulsas el botón una décima de segundo saltará 1 metro, si pulsas 3 décimas saltará 2 metros, si pulsas medio segundo saltará 3 metros y si dejas el botón pulsado 35 años saltará 3 metros igual que es el máximo.


El primer problema que he tenido son con las formas de añadir la fuerza al rigidbody, tiene 4 modos: fuerza, impulso, aceleración y cambio de velocidad. Son las combinaciones de usar o no masa, y usar fuerza constante o instantánea. Si usamos masa (fuerza e impulso), la fuerza que apliquemos será diferente si empujamos un objeto ligero o uno pesado, el problema es que la masa por defecto del rigidbody es 1, así que si haces las pruebas sin fijarte mucho puedes no notar diferencia. La diferencia entre fuerza constante e impulso puede ser más difícil de ver. En realidad es la diferencia entre considerar la fuerza como aceleración o como velocidad, las que son de tipo impulso instantáneo (impuso y cambio de velocidad), dividen entre el tiempo (delta time), mientras que las de impulso constante (fuerza y aceleración) lo hacen entre el tiempo al cuadrado, por eso la fuerza dada en forma de instantánea es mayor que si lo hacemos de forma continua.

El salto se controla con 3 parámetros: la potencia inicial de salto (o potencia mínima del salto), la potencia que aumenta el salto en cada frame que sigue pulsado el botón, y el tiempo máximo que cuenta el botón como pulsado. Aquí podríamos tener un problema, ya que al no tener un salto máximo, sino un tiempo máximo y el impulso ir aumentando por frames, tendríamos que saltaríamos más alto según el framerate de la aplicación. Realmente no llegamos a tener el problema por dos razones. Al aplicarla a través del rigidbody, se aplica teniendo en cuenta el tiempo entre frames, como explico en el párrafo anterior. Y además la gestión del salto se hace en un fixedUpdate, es decir a una tasa de frames constante (exactamente un frame cada 0.02 segundos), lo que hace que el salto sea muy estable.

Tuve problemas tontos en la implementación, primero por confundir las funciones para obtener las pulsaciones de botones (la de cuando se pulsa el botón, y la de cuando se mantiene pulsado), y después porque confundí funciones del nuevo controlador de personaje e intentaba hacer el impulso extra en la función que gestiona el movimiento en el suelo, lo que daba como resultado un extraño movimiento continuo de mini-saltos.

Una vez solucionado todo el salto iba bien, aunque con un extraño problema, había veces que daba al botón de salto y no saltaba. Tenía que dar otra vez al botón, y no conseguía imaginar por qué pasaba eso. Y es que el problema no estaba en mi lógica interna, sino en el uso del fixed update para el salto. De hecho gestionar el salto en el fixed update está muy bien, el problema es detectar la pulsación de teclas ahí, ya que hay eventos como el de tecla pulsada que solo se da durante un frame y si tienes un framerate mayor que el del fixed update puede suceder durante un frame que no tratas. Así que la solución era detectar la pulsación de botones en el update y gestionar el salto en el fixedUpdate.


Capsula mal colocada
Y todavía quedaba otro detalle, al saltar, la capsula no se ajusta bien al personaje, la cabeza queda fuera, por lo que podría atravesar algún techo bajo, eso me importa menos, pero sobre todo la capsula quedaba por debajo del personaje, lo que significa que podemos ver como el personaje llega a subirse a algo, pero inexplicablemente se choca y no llega. Eso si me importa más. Así que hice lo que no conseguí la última vez, ajustar el alto de la capsula y su posición vertical mediante curvas en la animación. Lo malo es que eran muchas animaciones, 7 en salto, 3 al estar en suelo y una de estar agachado (recepción de salto), así que hay que crear 22 curvas, tanto del estado donde tengo problema como de los estados con transiciones a ese estado. Es un poco coñazo, pero funciona bien, ahora la capsula se ajusta bien a la animación. 

Capsula bien colocada

No hay comentarios :

Publicar un comentario