Decía en el último artículo que ya
tengo la cámara funcionando como quiero, y que los
problemas de rendimiento no eran culpa del sistema de cámara. En
este artículo voy a cubrir cómo funciona la cámara al final y
pequeños problemas y sus soluciones.
El sistema básico tiene las ideas que
expliqué en el artículo sobre la segunda
versión de la cámara. Tener trozos de spline de 5 nodos, con
nodos equidistantes, y donde el último tramo de un spline y el
primero del siguiente se suponerponen haciendo una transición suave
entre un spline y el siguiente en esa parte en común. Lo que al
final se queda fuera es la aproximación de la posición del
personaje al spline por trozos de spline. Ahora mismo sigo
aproximando el spline como una recta para saber a qué altura del
spline está el personaje. En mis pruebas no se nota diferencia entre
las dos aproximaciones y es más barata.
Uno de los problemas que tenía desde
el principio de los tiempos y que pensaba que el usar la transición
suave entre 2 splines se iba a arreglar era el de los puntos muertos
en los empalmes de splines. Se entiende mucho mejor con una imagen de
estas cutres que dibujo tipo paint (pero que uso programas de los
buenos para hacerlos, el manco soy yo, no el sw):
Las rectas azules y verdes son la aproximación de 2 splines, los cuadrados de su color es la zona que la aproximación que hago consideraría como dentro de ese spline, entre 0 y 1 en coordenadas del spline. Y la x roja la posición del personaje. Y ahí está el problema está por encima del 1 para el primer spline, así que intentará dibujarlo con el valor del spline 2, y en el siguiente frame vería que el valor del spline 2 es negativo e intentaría dibujarlo con el valor del spline 1. Incluso he tenido implementaciones en que este problema daba un bucle infinito al usar recursividad y me tocaba matar Unity (por cierto, una forma de matar tu juego sin matar el editor estaría muy bien Unity). Si no el problema es que hay un punto en el que estando el personaje quieto, la cámara vibra entre dos tomas, que a lo mejor son muy cercanas, pero la sensación de parpadeo entre las dos es horrorosa, y no solo es si te pilla quieto en ese sitio, al pasar por él, aunque solo vibre una vez, se nota que ha pasado algo raro. El dibujo es una versión muy exagerada, nunca hay tanto hueco entre dos splines, pero siempre hay un pequeño hueco, sobre todo si nos alejamos del spline (a un lado en la cámara del juego), y lo mismo pasas varias veces por allí sin percibir el error, pero en alguna partida se ve, y no mola.
Y hay otra cosa que he pasado por alto
en el ejemplo y es que ahora los splines se superponen un poco, es
decir el final del spline 1 no es el principio del 2, sino que el
[75%-100%] del 1 coincide con el [0%-25%] del 2. Así que no debería
tener ese problema ¿o sí?, realmente lo único que he hecho es
desplazar los valores donde ocurre, pero sigue ocurriendo. Un ejemplo
práctico: posición en el spline 1: 100.01%, hay que dibujarlo en el
spline 2, donde tiene la posición 24.95%, en el siguiente frame:
24,5% es menor a 25%, así que debe dibujarse en el spline 1. Y así
tenemos un parpadeo constante, si cada frame se coloca la cámara en
un sitio un poco distinto. Claro, es que teniendo todo un tramo para
hacer los cambios, lo hago en el mismo punto al avanzar y al
retroceder, separando los dos puntos clave no tengo ese problema. Así
ahora al avanzar se cambia de un spline al siguiente cuando alcanza
el 100% (y sigue por el 25% del siguiente), pero al retroceder, se
hace cuando bajo del 15% del spline (siguiendo hacia abajo por el 90%
del spline anterior). Y así, por mucho error de aproximación en los
empalmes que haya, no puede ser de un 10% y no tengo ese fenómeno
del parpadeo.
Relacionado con esto está el error de
índice fuera de rango que obtenía a veces y que no sabía de donde
venía, y el problema es el mismo. Cuando llego al 75% de un spline
se toma posición respecto a ese spline y respecto al siguiente y se
va interpolando entre las 2. Por ejemplo: 0.8 en un spline en
realidad tomo un 80% de la posición del primer spline al 0.8 y un
20% del segundo spline al 0.5. Justo al llegar a 0.75, puede pasar
que el segundo spline me de un valor de -0.02, por ejemplo, y ese
valor negativo es lo que me hacía saltar por los aires el método
para calcular posiciones de spline de iTween. Por encima de 1, el
método extrapola valores muy bien, pero por debajo de 0 peta.
Sabiendo esto y añadiendo unos clamps por ahí la solución era
fácil, lo difícil era darse cuenta del problema, sobre todo porque
se daba en ocasiones contadas, no era fácil de reproducir.
Otro problema era la orientación de la
cámara. Para no hacerlo caro intenté aprovechar la última posición
de la cámara y la actual para ir enfocando hacia la tangente. El
primer error saltaba inmediatamente: si el jugador se paraba la
posición anterior y la actual son la misma y la cámara se pone a
mirar para cuenca. Solución fácil: comprobar la posición, si es la
misma y el jugador no se ha movido pues no hacemos caso y seguimos
con la anterior posición registrada. Pero volvemos a tener un
problema de precisión. ¿Y si el jugador se ha movido muy poco? ¿Y
si no se ha movido pero por un problema de precisión Unity cree que
si? En estos casos puede que los operadores de comparación fallen al
ser dos cifras muy parecidas y haga lo que lo debe, ponerme la cámara
mirando al revés. Es un caso raro, pero he conseguido dando vueltas
por algún punto conflictivo que la cámara mire justo hacia el sitio
contrario de donde debería. ¿Y qué hago? ¿Pongo un umbral de
movimiento? Esto podría tener un problema, que alguien se moviese
muy muy despacio y la cámara no le siguiera al no detectar el
movimiento.
Lo podría hacer acumulado, no tomar
una nueva posición para la orientación hasta que no se haya
desplazado un mínimo desde la anterior, pero sigo teniendo
problemas. A veces da saltos, porque el diferencial usado para
separar los puntos no es siempre el mismo y se nota mucho el tirón.
Intenté también usar posiciones pasadas cuando sea posible e
inventarlas con un desplazamiento sobre el spline cuando no. Aquí el
parpadeo era evidente, la diferencia de orientación cuando se usaba
uno u otro método era muy evidente. Tras descubrir que los problemas
de rendimiento no eran por la cámara pude dejarme de tanta tontería
y tomar siempre dos medidas de cámara para poder orientarla. Ahora
si la cámara acaba en una posición x (en spline) calculo su
posición en coordenadas del mundo y la posición de x+0.1 y pongo la
cámara a mirar en la dirección de la tangente generada por estos
dos puntos. Así el movimiento de la cámara es bastante suave.
El último problema que tuve fue la
orientación inicial de la cámara. El jugador empieza algo por
detrás del punto 0 de la cámara, y tanto la posición de la cámara
como la auxiliar para orientación quedaban por debajo de 0, siendo
clampeadas a 0 y teniendo otra vez la cámara mirando para cuenca.
Con un poco de precaución del orden en que hacer la suma de valores
extra y los clamps esto también se solucionó.
En el vídeo se puede ver como ahora
funciona bien y suave. Hacia el final del desfiladero hace un giro
brusco, es por cómo he puesto los splines, sin preocuparme mucho
(espero), ya que como va a cambiar la fase, tendré que poner que la
cámara vaya por otro sitio y no merece la pena dedicarle mucho
tiempo. Otra cosa que se ve en el vídeo es que ahora solo 1 veneno
se activa ante el personaje y ataca, ya os contaré el problema, ¡me
pongo ahora mismo con ello!
No hay comentarios :
Publicar un comentario