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.
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