Jump to content
Sign in to follow this  
Jhonatan00_00

Scripting de Animación

Recommended Posts

Buenas tardes, después de mucho tiempo intentando que las animaciones vayan perfectas en todas las circunstancias he llegado a la conclusión de que el Animator (aunque es muy práctico a la hora de crear transiciones, etc) es bastante limitado y a menudo falla obligándote a tener que ingeniártelas para que todo funcione correctamente.

Por ejemplo tengo un personaje con multitud de animaciones y se da el caso de que esté parado, pulsemos el botón de avanzar y justo después (si sabes hacerlo en el momento preciso) saltes y se produzca una transición entre dos estados que no debería de haber ocurrido. También se da el caso de que estés corriendo y caigas, pero si la caída no es lo suficientemente alta como para que de tiempo a hacer la transición entre la animación cayendo y la animación de haber tocado suelo, se producen animaciones muy poco realistas que no quedan bien.

La mejor solución creo que es controlar las animaciones por script (cuando son complejas y tienen muchas variantes), para hacer que justo en el momento en el que toque suelo haga su animación de haber tocado el suelo, independientemente de que se encuentre en un estado saltando, corriendo, etc (por poner un ejemplo). El problema es que no conozco todos los comandos que podrían facilitar esta tarea de programación y quisiera que los fuésemos recopilando aquí, por ejemplo yo conozco estos:

GetComponent<Animator>().Play ("Animacion");    //Sirve para reproducir un estado de animación instantátenamente.

GetComponent<Animator>().CrossFade ("Animacion", 0.2f);    //Sirve para iniciar una transición o interpolación desde el estado en el que nos encontremos al indicado.

¿Como indicamos por medio de script por ejemplo que si no pulsamos ninguna tecla la animación a reproducir sea la de reposo?.

Un slaudo.

 

 

Share this post


Link to post
Share on other sites

Buenas tardes Francoe1, llámalo invocar o llámalo reproducir... en la práctica lo que hace es que se reproduzca una animación de un estado sin tener que haberlo montado en el Animator con ningún booleano, etc, simplemente utilizas este comando y se reproduce la animación... Lo que necesito saber es que mas cosas puedo hacer por medio de script que sean practicas para hacer animaciones.

¿Existe alguna forma de indicar por script que la animación por defecto sea la de reposo, para que cuando no toquemos ninguna tecla se inice o tenemos que usar a la fuerza también el ().play?. Estoy viendo de que forma puedo montarlo todo por script pero que tampoco sea demasiado complejo.

Share this post


Link to post
Share on other sites
On 2/5/2021 at 1:12 PM, Jhonatan00_00 said:

Por ejemplo tengo un personaje con multitud de animaciones y se da el caso de que esté parado, pulsemos el botón de avanzar y justo después (si sabes hacerlo en el momento preciso) saltes y se produzca una transición entre dos estados que no debería de haber ocurrido. También se da el caso de que estés corriendo y caigas, pero si la caída no es lo suficientemente alta como para que de tiempo a hacer la transición entre la animación cayendo y la animación de haber tocado suelo, se producen animaciones muy poco realistas que no quedan bien.

Todo eso me suena a que no estás haciendo 2 cosas:

  1. Seteando la prioridad de las transiciones, Selecciona un estado y fijate que en el inspector te figuran en order, de arriba (más prioridad) a abajo (menos).
  2. Configurando la fuente de interrupción de cada estado (https://docs.unity3d.com/Manual/class-Transition.html#TransitionInterruption), ya que se puede dar que una transición esté pasando, pero un estado (el actual o el siguente) tenga una transición valida al mismo tiempo.

Respecto a 2, esto dice la doc:

Value Function
None Don’t add any more transitions.
Current State Queue the transitions from the current state.
Next State Queue the transitions from the next state.
Current State then Next State Queue the transitions from the current state, then queue the ones from the next state.
Next State then Current State Queue the transitions from the next state, then queue the ones from the current state.

 

Ejemplo de un personaje que está en el estado "caida" y pasa a "suelo" al caer (isGrounded = true). En plena transición le das a la tecla de salto, es decir, deberías pasar de "suelo" a "salto".

Volviendo al isGrounded = true, un trigger se llama, ahora está en plena transicion a "suelo". Vamos a suponer que todavía no estás en "suelo" (que es el proximo estado, el "next"), entonces sigues en "caida" (el actual o "current"), por lo que si presionas la tecla de salto no pasa nada (a nivel animación, probablemente el objeto físico salte, eso no nos importa de momento). La cosa que la animación no cambia, todo termina en "suelo" eventualmente. Si configuras que la fuente de interrupción sea "Next", lo que va a pasar es lo siguiente:

  1. Hay una transición que require accionarse ya mismo ("suelo -> salto" dió válida)
  2. Dicha transición pertenece al estado siguiente "suelo" (next). Recordar que los estados contienen a las transiciones si tienen su cola (no su punta). En este caso suelo contiene "suelo -> salto", salto tendrá "salto -> caida", caida tendra "caida -> suelo" , y así...
  3. El estado actual (caida) tiene como fuente de interrupción el estado Next ("suelo", quien contiene la transición a salto y encima es válida)
  4. El sistema suma dos más dos y termina interrumpiendo la transición actual de inmediato, en base a la "interruption source" de arriba.

Todo esto no hubiera terminado bien si tuvieras current como fuente de interrupción. Si no estás seguro metele "Current state then next state".

 

On 2/5/2021 at 1:12 PM, Jhonatan00_00 said:

El problema es que no conozco todos los comandos que podrían facilitar esta tarea de programación y quisiera que los fuésemos recopilando aquí, por ejemplo yo conozco estos:

Documentación.

Como dijiste, esas son las dos más usadas, Play reproduce de una, Crossfade te da una transición de donde estés hacia el estado target.

On 2/5/2021 at 1:12 PM, Jhonatan00_00 said:

¿Como indicamos por medio de script por ejemplo que si no pulsamos ninguna tecla la animación a reproducir sea la de reposo?.

Pasa que eso es muy confuso, que pasa si estás saltando (que se yo, 100 metros en el aire) y a los 3 segundos (llegaste al pico) no presionas nada? tenés que andar leyendo el estado actual, y en base a eso determinar si das Play/Crossfade a X animación... terminas creandote la misma herramienta dentro del código. Creeme que yo vengo puteando con Mecanim desde hace años, y todos los problemas (excepto los más estúpidos y fáciles de solucionar) tienen su vuelta.

Te recomiendo lo de las prioridades y las fuentes de interrupciones.

Edited by lightbug
  • Like 3

Share this post


Link to post
Share on other sites

Buenos días Lightbug, el principal problema es que estoy usando la versión de Unity 4.7.2 y no incluye las opciones que me indicas. De todo lo que me has enseñado tan solo he podido poner en práctica lo de dar prioridad a las transiciones (que no sabía que se podían ordenar por prioridad), pero aún así me sigue haciendo cosas raras.

Por ejemplo mi personaje puede volar y si al caer tocas el suelo y pulsas rápido la tecla de saltar a veces me inicia la animación de salto y otras veces hace un intento de animación de volar con posturas raras como si estuviese corriendo al mismo tiempo, es rarísimo. Cosas así son las que quiero impedir que pasen y aunque solo pasan en momentos puntuales quisiera solucionarlo.

Se que me vas a decir que actualice Unity y lo he hecho varias veces, pero cada vez que actualizo me arrepiento porque Unity me estropea todo el trabajo realizado, la iluminación y muchas otras cosas y tengo que volver a la versión que tenia. Por medio de script debería de poder dejarlo todo perfecto para que no pasen estas cosas que parecen confusiones del Animator.

He conseguido que funcione bien sincronizada la animación de tocar el suelo con GetComponent<Animator>().CrossFade ("Tocando_Suelo", 0.8f); De este modo justo cuando toca realiza su animación sin hacerme cosas raras, pero hay un problema y es que al parecer el tiempo de transición tiene en cuenta la duración de la animación inicial, quiero decir, si la animación de correr es mas larga que la animación de salto Unity mezclará las animaciones de una forma mas lenta o mas rápida aún teniendo el mismo tiempo de transición de 0.8f, dependiendo de la duración de la animación de la que venga.

¿Cómo puedo indicar que siempre sea el mismo tiempo de transición sin importar lo que dure la animación inicial?.

Edited by Jhonatan00_00

Share this post


Link to post
Share on other sites

Buenas tardes, ya no se que hacer... conforme el personaje tiene mas animaciones funcionan peor. Entre el trabajo que a veces no me deja echarle un rato al juego y que me desmotivo y lo dejo un montón de tiempo porque hay problemas que no puedo solucionar no termino el juego en la vida... Al final lo terminaré dejando como todo a medias, porque son demasiadas cosas que no funcionan bien 🤣

¿Alguna idea o truco, script, etc para que las animaciones funcionen a la perfección?. He probado de todo y me hace cosas muy raras.

Share this post


Link to post
Share on other sites

Buenos días compañeros!!, por fin he solucionado mis problemas con el Animator, aunque no del todo, pero quiero dejar aquí la solución para que no le pase a nadie mas.

Unity tiene un orden de transiciones, pero ese orden al menos en la versión 4.7.2 que es la que uso yo, no funciona correctamente hasta que no aprendes a utilizar "Atomic", que es una casilla que por defecto viene marcada, pero que al desmarcarla significa "NO PASAR A ESTA ANIMACIÓN SI ANTES ESTÁ EJECUTANDOSE OTRA QUE ESTÉ PRIMERO EN EL ORDEN DE TRANSICIONES".

Quiere decir, que si le damos a correr y a saltar al mismo tiempo, Unity podría intentar hacer la animación de correr y después la de saltar creando una pose extraña, mientras que si destildamos la casilla Atomic y colocamos en la lista de transiciones la pose de saltar en primer lugar, Unity antes de iniciar la animación de correr iniciará la de saltar porque tiene prioridad.

Esto me ha solucionado el 90% de los errores de animación, pero aún hay otros como que por ejemplo esté realizando una transición y quieras interrumpirla, que creo que lo voy a tener que hacer con programación, porque esta versión de Unity no tiene el Has Exit Time.

Saludos.

  • Like 2

Share this post


Link to post
Share on other sites
Sign in to follow this  

×
×
  • Create New...