lunes, 2 de febrero de 2015

Cambio de gravedad con SuperCharacterController

En la entrada anterior presentaba el SuperCharacterController, y los cambios que había hecho, y en esta me reservo el cambio principal, el control de gravedad, vuelvo a poner el vídeo para que se vea de qué hablo.



Siempre tenía la duda de en el caso de tener una cámara libre se aplicase el cambio de gravedad hacia donde cambiaría. Es decir, si damos al botón de cambiar la gravedad hacia la izquierda, hacia donde debería cambiar la gravedad, ¿según el vector left del personaje?, ¿el vector left de la cámara?. Si se hiciera con el del personaje sería un lío, por ejemplo si el personaje está mirando hacia la pantalla (le vemos la cara) y cambiamos la gravedad a su izquierda, en realidad la cambiamos a nuestra derecha. ¿queríamos hacer eso? Seguramente no. Así que para facilidad del usuario, me parece lógico que se cambie siempre según su punto de vista. Ahora bien, al tener una cámara libre, podríamos estar mirando en cualquier dirección, eso significaría poder poner la gravedad en cualquier dirección, completa libertad, y cosas un poco raras. ¿Gravedad mirando hacia una esquina?

Encontré una solución haciendo que la gravedad se ajuste al eje más próximo. Es decir, imaginemos que el personaje está moviéndose en diagonal, pero lo más cercano es el eje +z, entonces al girar la gravedad a la izquierda, la gravedad pasará de -y a -x. Es un sistema que funciona bastante bien en un escenario como el de la demo, donde las paredes son rectas y alineadas con los ejes. Al tener una cámara sobre raíles siempre puedo hacerlo respecto a la cámara, pero si sigo haciéndolo ajustado a los ejes y hago que los escenarios también sean ajustados a los ejes intentando que no se note mucho que todo es muy cuadradote. La ventaja es que así puedo realizar puzles y retos de forma sencilla y fácil de probar y evito muchos posibles bugs y tampoco vuelvo loco al jugador.


Una desventaja de tener la cámara fija en los cambios de gravedad, es que todo tiene que estar a la vista para el jugador desde la cámara, no puedes dejar algo muy alto donde ir, porque el jugador no puede mirar hacia arriba para ver que hay y por lo tanto la solución a ese puzle sería un salto de fe. No mola.


Control de gravedad

La parte de implementación no ha sido sencilla. Quería que el personaje se elevase un poco y girase en el aire antes de caer en la nueva dirección de la gravedad. De esta forma aunque hagamos el giro muy cerca de una pared, funciona bien y tenemos un momento claro para ver hacia donde giramos. La clase que controla los comportamientos del personaje es una máquina de estados finitos. Así que añadí dos estados nuevos, uno para la parte de elevarse y otro para el giro.

No ha sido trivial conseguir que todo este sistema ya hecho funcione en cualquier dirección, que la cámara funcione bien cuando estamos andando sobre una pared, y el movimiento, el salto, las detecciones de colisiones... Y aquí me han sido bastante útiles los cuaternios. Por suerte Unity usa por defecto cuaternios para las rotaciones, y el controlador que he usado como base también. Aunque entender bien la esencia de los cuaternios es un verdadero lío, llegando a las hiperesferas y con 3 números imaginarios, usarlos es relativamente sencillo y algunas cosas las salva enormemente. Por ejemplo cuando hago el giro lento en el aire, tengo que interpolar entre 2 rotaciones, algo sencillo con cuaternios, un coñazo increíble con otro tipo de representación de las rotaciones. Y otro de los problemas que he tenido fue para determinar cuándo has llegado a una rotación meta. Primero intenté ir mirando la diferencia con el ángulo en un cierto eje, lo cual funciona bien en la primera rotación, pero cuando se acumulan las rotaciones (es decir más de un cambio de gravedad consecutivo en diferentes ejes) hay que anular ciertos ejes para no confundirse y a veces ni con esas porque unos giros anulan otros y puede que la situación final sea una combinación de ángulos que no esperabas. Todo esto haciendo una comparación componente a componente entre 2 cuaternios no pasa y todo es más sencillo.

Pero no todo es perfecto, hay una cosa que se me ha escapado, he intentado que no se vea en el vídeo, pero el giro vertical de la cámara no funciona bien con la gravedad cambiada. He intentado corregirlo durante algunas horas sin éxito, el giro horizontal funciona bien, pero el vertical puede ir en el eje que debe o en otro, dando giros repetidos o extraños de cámara. Como voy a utilizar una cámara sobre raíles sin libertad de manejo por parte del usuario no he seguido trabajando en eso, y al menos que al final cambie de idea y deje la cámara libre no lo volveré a tocar.

Ahora solo queda integrar todo este sistema, incluidos controles, colisiones, cámara y físicas dentro del resto del sistema del juego, el primer paso colocar la cámara sobre raíles con este sistema de control.

No hay comentarios :

Publicar un comentario