Curvas de animación, la palanca de diseño definitiva

EDUARDO ORIZ / UNITY TECHNOLOGIESSenior Content Marketing Manager
Jul 21, 2022|27 minutos
Curvas de animación, la palanca de diseño definitiva
Para tu comodidad, tradujimos esta página mediante traducción automática. No podemos garantizar la precisión ni la confiabilidad del contenido traducido. Si tienes alguna duda sobre la precisión del contenido traducido, consulta la versión oficial en inglés de la página web.

Esta es la tercera publicación de blog de Christo Nobbs en su serie para diseñadores de juegos. La serie amplía sus contribuciones a The Unity game designer playbook, una guía detallada de más de 100 páginas que instruye a los diseñadores de juegos sobre cómo crear prototipos, diseñar y probar juegos en Unity. Al final de este artículo se incluyen enlaces a publicaciones anteriores del blog de Christo.

En Unity, hay varios “tipos” que podemos usar para almacenar datos que son tan beneficiosos como palancas de diseño para equilibrar sistemas, jugabilidad, configuraciones de personajes, perfiles de vehículos, etc. Las curvas de animación son un tipo de componente que ofrece a los diseñadores y creadores de juegos posibilidades interesantes, especialmente a la hora de crear prototipos. Úsalos en tu proyecto, por ejemplo, dentro de un sistema de partículas para controlar variables animadas, o dentro del componente de fuente de audio para administrar la atenuación y otras propiedades.

Una curva es un gráfico lineal que muestra la respuesta (en el eje Y) al valor variable de una entrada (en el eje X). Unity utiliza curvas en una variedad de contextos diferentes, específicamente en animación. Los editores de curvas tienen varias opciones y herramientas diferentes que puedes aprovechar.

Esta publicación se centrará en trabajar con curvas de animación a través de la API de Unity , con el tipo de variable AnimationCurve. De esta forma, se pueden utilizar para capturar y almacenar datos, lo que resulta útil para analizar resultados. Las curvas también son compatibles con ScriptableObjects, que, como se explica en el manual, son excelentes para editar datos del juego.

Las curvas de animación se pueden editar dentro del Inspector como variables públicas o cuando se serializan. Puede guardarlos, exportarlos o cargarlos en el modo de edición o en tiempo de ejecución. Las tangentes editables permiten controlar la forma de la curva entre las teclas.

Una propiedad de Curva de animación en el Inspector
Una propiedad de Curva de animación en el Inspector: Al hacer clic en él, se abre el Editor de curvas, donde puede ajustar la curva y guardarla en su propia biblioteca seleccionando el ícono del engranaje.
La clave de una tangente en Unity
Al hacer doble clic en una curva, se crea una nueva clave que puede usar para manipularla y también proporciona varias opciones para controlar los controladores de la clave.

Puede agregar claves, alterar sus tangentes y manipular controladores en la curva para encontrar la forma que proporcione los resultados deseados.

Una curva de animación con múltiples tangentes
Una curva de animación que incluye tangentes para crear picos, valles y ángulos abruptos orgánicos.
Añadiendo detalles realistas al movimiento y la acción cotidiana.

Una palanca de diseño visual como una curva de animación permite a los diseñadores de juegos perfeccionar la jugabilidad sin tener que escribir operaciones matemáticas complejas o funciones de facilitación.

Una forma de utilizar curvas de animación es en una línea de tiempo, para agregar matices y detalles a los movimientos lineales. Tomemos el ejemplo de un personaje que cierra la puerta de un coche. La acción comienza con un movimiento cuando la mano agarra la palanca para cerrar la puerta. Al principio, la puerta se cierra lentamente, pero el movimiento se acelera a medida que la puerta se cierra y luego termina con una parada abrupta; quizás con un pequeño rebote o clic. Todos estos movimientos se pueden guardar dentro de la misma curva para la secuencia.

Una puerta marrón que se abre y se cierra sobre un árbol verde en el editor de Unity
Una puerta que se abre y se cierra utilizando curvas en la línea de tiempo de la animación.
La curva para abrir una puerta
La curva para abrir una puerta
La curva para cerrar una puerta
La curva para cerrar una puerta

Como muestra este ejemplo, las curvas de animación son beneficiosas para cambiar las propiedades de un objeto a lo largo del tiempo y crear un movimiento de apariencia natural. Otros casos de uso se centran en cómo un objeto se mueve o gira, cómo un personaje acelera o desacelera al iniciar o finalizar un sprint, o cómo un motor entrega potencia a un controlador de automóvil.

Código C# de curva de animación
Vea esta descripción general de cómo una curva de animación en el Inspector devuelve datos en el eje Y en una posición determinada en el eje X. El método inferior muestra cómo utilizar el método EvaluateCurve pasando la curva y la posición deseadas.

Cuando creas una curva de animación para editar en el Inspector, podrás evaluar la curva pasando un parámetro, denominado tiempo en Unity. Más adelante en esta publicación, veremos por qué la posición es más descriptiva cuando no se utiliza el eje X para el tiempo.

Una curva de par motor “pseudo” para controlar la potencia de salida del motor

Examinemos cómo se puede utilizar una curva de animación para controlar la potencia de salida del motor de un vehículo. Puede crear una curva de torque del motor “pseudo” para devolver la fuerza aplicada al vehículo en función de las RPM (revoluciones por minuto) actuales del motor. Esto aumenta con el tiempo si el jugador presiona el acelerador.

En lugar de mapear el rango completo de RPM para cada marcha y vehículo, puedes “normalizar” o establecer las RPM entre 0 y 1. Las curvas de “torque” que cree se pueden guardar y reutilizar para otros vehículos y engranajes.

Establezca este valor dividiendo su valor bruto o actual por el valor máximo:

normalisedCurrentRPM = currentRPM / maxRPM

La potencia de salida (eje Y) también se utilizará entre 0 y 1 para mantener el Editor de curvas manejable y las curvas en sí reutilizables. Este valor se puede agregar a la fuerza de movimiento del vehículo, para mover el Rigidbody del vehículo hacia adelante en el eje Z.

Un ejemplo de script para normalizar el RPM
A continuación se muestra un ejemplo de script para “normalizar” las RPM y luego agregar una fuerza basada en el valor Y de la curva de torque a las RPM dadas multiplicado por la potencia del motor.

Puedes crear varios resultados con la misma configuración para otros vehículos manteniéndote entre los valores de 0,0 y 1,1 en la curva.

Una curva verde ascendente

Agregar una ecuación de relación de transmisión básica al motor de su automóvil puede dar como resultado vehículos de apariencia realista que se mueven y se balancean a medida que pasa por las marchas y alcanza diferentes curvas de potencia, o la misma curva en diferentes puntos. Esto requiere que el coche sea un Rigidbody. A medida que agrega otros Rigidbodies en el maletero o en los asientos traseros del automóvil, el automóvil tendrá un movimiento impactado, lo que puede ser divertido para misiones de entrega cronometradas.

Si no desea utilizar el sistema de física de Unity porque tiene un controlador de automóvil personalizado, puede crear variantes con y sin carga de sus curvas e intercambiar estas curvas en tiempo de ejecución para lograr que el vehículo se conduzca de la manera deseada.

Aunque no usarás esto con frecuencia, puedes agregar claves, modificar claves (lo que elimina y agrega nuevas claves) y eliminar claves por completo en las curvas en tiempo de ejecución a través de la API de Unity . Esto le brinda más control sobre la modificación de sus curvas, lo que también puede incluir suavizar tangentes según sea necesario.

Curvas para un vehículo pesado, como un camión con cambios automáticos que arranca lentamente pero luego no pierde potencia después de alcanzar las RPM máximas: Esta curva muestra el camión sin carga.
Esta curva muestra un camión con una carga pesada. Al agregar otra llave y una reducción de potencia después de que el vehículo haya comenzado a moverse, puede hacer que el camión se sienta como si tuviera una segunda marcha prolongada, por ejemplo, lo que le da más personalidad.
Una sola curva para un vehículo que tiene múltiples marchas.
Una sola curva para un vehículo que tiene múltiples marchas.

Las curvas de animación le permiten crear excelentes abstracciones de sistemas más complejos que puede controlar en un formato visual. En el ejemplo del motor, puedes agregar potencia a lo largo del tiempo al acelerar con la curva que se muestra arriba (que representa la caja de cambios “pseudo”) para crear la sensación del auto cambiando de marcha, ajustando su paso hacia arriba a medida que se entrega potencia y luego hacia abajo nuevamente a medida que la potencia disminuye en la parte superior de cada marcha. Esto es ideal para crear un prototipo del movimiento de un vehículo al colocar toda la potencia del automóvil en una curva que mapea todos los engranajes, desde el inicio de la primera marcha en x0, y0 hasta la parte superior de la quinta marcha en x1, y1.

Las RPM generalmente se acumulan con el tiempo al acelerar, por lo que básicamente estás trazando valores a lo largo del tiempo, de forma muy similar a agregar movimiento lineal a un objeto en movimiento. Lea más sobre esto en la sección sobre tiempo y animación en el manual del diseñador de juegos.

Tres coches de aspecto futurista compiten en una gran carretera cuadriculada con luces de neón azules que rodean la carretera.
La física “pseudo” es útil en juegos donde el movimiento no se ajusta a las reglas de la física de la vida real, como en el juego de carreras futurista hecho con Unity , Antigraviator.

Tomemos otro ejemplo: la suspensión y el movimiento de un automóvil cuando circula por un terreno irregular, en curvas o cuando se transmite potencia a las ruedas. Con Curvas de animación se puede mejorar la dirección, controlar las fuerzas laterales o el deslizamiento de los neumáticos para crear resultados realistas que se pueden perfeccionar visualmente.

Al crear mecánicas basadas en raycast para un vehículo, ya sea un vehículo flotante o con ruedas, una opción común para crear el efecto de "suspensión" en el motor es una fuerza ascendente aplicada en cada rayo y un algoritmo de controlador PID (proporcional-integral-derivativo) para controlar el rebote o, en algunos casos, la ley de Hooke para la amortiguación. Un ejemplo de esto se puede ver en Hover Racer Live 7/21 Cycle 4.2de Unity, junto con un ejemplo más adelante en esta publicación que utiliza un PID basado en él.

Un algoritmo de controlador PID es un mecanismo de retroalimentación de bucle de control, o un controlador, utilizado en muchas industrias, incluido el desarrollo de juegos, cuando se necesita una corrección de respuesta. El controlador PID calcula un valor de error como la diferencia entre una variable de proceso medida y un punto de ajuste deseado y, en relación con la elasticidad (o nuestro ejemplo dado), se puede utilizar como una alternativa a la ley de Hooke. Un PID en los juegos también es práctico para:

  • Hacer que un vehículo regule una velocidad objetivo en el modo de control de crucero, mientras está sujeto de manera impredecible a otros factores como la masa transportada, la entrada del jugador o la angulación del terreno.
  • Controla cuánta precisión tienen los agentes de la IA enemiga al disparar a tus jugadores, mientras evitan ser alcanzados.
  • Predicción de latencia en juegos multijugador.

Los PID se pueden utilizar en cualquier parte del desarrollo de juegos, especialmente en entornos sandbox y simulaciones que requieren “un control automático preciso y optimizado”. Kerbal Space Program de Squad utiliza PID para mantener una nave espacial en una sola dirección.

Según este estudio, “la regulación PID es la tecnología más madura y ampliamente utilizada de sistemas continuos” fuera del desarrollo de juegos. Mira esto Conferencia sobre sistema de control: Introducción al control PID Para obtener información adicional.

Un cohete espacial está en un hangar, con una interfaz abierta a la izquierda, que muestra opciones de personalización para el cohete.
Kerbal Space Program de Squad, disponible en Steam, utiliza algoritmos de controlador PID.

Los algoritmos del controlador PID pueden no requerir mucho tiempo para realizarse, pero sí requieren tiempo para equilibrarse; tiempo que se multiplica dependiendo de cuántos vehículos tengas. Sin embargo, al crear prototipos, puede utilizar una curva de animación para ahorrar tiempo o evitar los desafíos técnicos de implementar y equilibrar múltiples controladores PID (eventualmente querrá reemplazar la solución de curva con un PID para un control máximo).

Las curvas son ideales para la creación de prototipos porque se pueden usar para hacer coincidir visualmente ejemplos de referencia de objetivos del mundo real. En lo que respecta al espacio, esto es “matemáticamente perfecto” en un motor de juego, sin fuerzas de movimiento opuestas a menos que se agreguen o se habilite la gravedad predeterminada. Por lo general, resulta más fácil utilizar una curva simple para controlar el cambio y yield resultados sólidos.

En el caso de crear la suspensión de un vehículo, puede utilizar Curvas de animación para informar cuánta fuerza opuesta se aplica en función del nivel de compresión del resorte (normalizado entre 0 y 1), en lugar de utilizar un controlador PID para crear la amortiguación. Combinado con un Rigidbody y una pequeña cantidad de resistencia, se suprime la oscilación de rebote y la suspensión del vehículo reacciona al aumento o la disminución de la carga.

Para determinar la compresión del resorte, debe restar la distancia de impacto del rayo de la longitud del resorte de 1.0f. Independientemente de su longitud, cuando el resorte está al 25% de compresión, el valor de compresión será 0,25. Establezca este valor de compresión como el valor X en la Curva de animación, multiplíquelo por la fuerza de resorte deseada (porque está trabajando con valores normalizados) y luego úselo en AddForceAtPosition para aplicar la fuerza hacia arriba en cada punto de un bucle, según la cantidad de puntos de suspensión. No se necesitan fuerzas descendentes adicionales aparte de la gravedad predeterminada de Unity a -9,81f.

Aquí está la fórmula:

upwardsForce = forceMultiplier * forceCurve.Evaluate(springCompressionNormalized);

rigidBody.AddForceAtPosition(hitNormal * upwardsForce, point.transform.position);

Utilizando una relación masa:fuerza de 13:110 y la siguiente curva.

Una camioneta blanca sin ruedas cayendo en una carretera frente a un bosque, en Unity
Furgoneta sin ruedas con longitudes de suspensión mayores (longitud de resorte de 1 metro): La camioneta cae en un ángulo desigual, en línea recta, y se balancea hacia adelante y hacia atrás.
Una curva sigmoidea doble
Una curva sigmoidea doble

El vehículo se asienta en aproximadamente un 50 % de compresión utilizando valores adecuados de masa, fuerza ascendente y pequeñas cantidades de resistencia lineal y angular para suprimir la oscilación. Esto permite que el vehículo rebote y se asiente, pero no toque fondo, a menos que se caiga desde una altura extremadamente alta o el jugador lo sobrecargue al agregarle masa.

Para encontrar buenos valores, comience con una curva y = b^x (que parece similar a un cuarto de círculo). Mantenga baja la resistencia y ajuste la masa del vehículo a lo que es en realidad. Luego se ajusta la fuerza ascendente hasta que el vehículo se asienta en aproximadamente un 50 % de compresión del resorte. Deje caer el vehículo unas cuantas veces para comprobar si toca fondo y ver dónde se asienta después del rebote. El uso de este enfoque para la suspensión de vehículos que circulan por terrenos irregulares, donde se puede ganar o perder cada punto de tracción, permite obtener un sistema de suspensión rápido y controlable.

El uso de curvas de animación para su modelo de suspensión puede garantizar movimientos variados para vehículos (automóviles, camionetas o camiones con mala suspensión), es decir, aquellos que tocan fondo todo el tiempo, rebotan como los de los juegos de arcade o ruedan en las esquinas y se tambalean cuando acelera y frena. Las curvas se pueden utilizar en combinación con sistemas existentes si aún no utiliza el sistema Rigidbody de Unity o su propio método de suspensión. Puedes utilizar curvas para dirigir o amplificar la potencia del motor, la suspensión, la resistencia, el deslizamiento de los neumáticos, la fuerza de frenado y más. Las curvas de animación son una herramienta muy útil y versátil en Unity para agregar palancas de diseño a cada vehículo para controlar sus características visualmente en el Inspector.

Bolas grises que caen con diferentes características y curvas en Unity
Usar diferentes curvas para cada Rigidbody para ver las características al soltarlo
Las curvas de cada esfera en la imagen anterior.
Las curvas de cada esfera en la imagen anterior.
Un fragmento de código en C# para eliminar objetos
El fragmento de código para dejar caer esferas

La fila de esferas en la imagen de arriba se creó posicionando una secuencia de Rigidbodies en una fila y restringiendo sus propiedades de Posición de congelación X y Z. Luego se aplicó una fuerza ascendente utilizando una Curva de animación basada en la fuerza ascendente de compresión, pero con diferentes curvas para cada esfera, colocadas una al lado de la otra para una mejor visualización. Puede utilizar esta técnica para encontrar el nivel de rebote deseado para un objeto o para ajustar el rebote existente para equilibrar las características. Como diseñador, poder manipular las características de la fuerza ascendente puede ayudarle a crear abstracciones de funciones más complejas.

Las curvas son un poderoso tipo de datos de gráfico XY y, aunque técnicamente no son perfectas, pueden ayudarlo a crear prototipos de soluciones de amortiguación rápidas que pueden editarse visualmente en el Inspector y guardarse como ajustes preestablecidos en tiempo de ejecución. En este blog sobre el arte de la amortiguación, Alexis Bacot destaca todas las cosas que “dependen de una buena amortiguación”. Cámara, animación, movimiento, gradientes de color, transiciones de UI y mucho más... ¡se usa en todas partes! Comprender la amortiguación es clave para lograr un excelente pulido. La amortiguación por sí sola puede marcar la diferencia entre una mala o una buena experiencia”.

En la misma publicación, demuestra cómo se puede usar SmoothDamp de Unity para crear una hermosa entrada y salida suave, y reacciona con precisión a los cambios de objetivo. Pero no rebota como un “amortiguador de resorte avanzado que puede oscilar, lo cual es excelente para la suspensión de automóviles o la física de pelotas falsas”, un ejemplo de dónde las curvas de animación brindan una poderosa ventaja.

Por supuesto, las curvas tienen más usos que como un tipo de datos XY para manipular el juego. También se pueden tratar como una herramienta de evaluación para capturar datos visualmente utilizando AddKey a través de la API de Unity . Para evaluar una posición a lo largo del tiempo, como la amortiguación en el ejemplo de la suspensión del vehículo o las esferas que caen, utilice AddKey(elapsedTime, currentSpringCompression) en un método y luego llame a ese método y pase captureResolution como la tasa de repetición a través de InvokeRepeating. Una resolución de captura de 0,1f significa que, cada 0,1 s, se añade una clave a la curva. Vea el mini resultado en el Inspector o abra el gráfico para ver los datos completos.

Una curva trazada
Una curva trazada es el resultado de utilizar una curva de rebote lineal que tiene una línea recta de 0,0 a 1,1.
Una curva trazada
Una curva graficada como resultado del uso de una curva no lineal, de tipo sigmoide doble, similar a la que se muestra arriba.
De vuelta a la furgoneta que rebota

Echemos un último vistazo a la furgoneta que está cayendo. La curva de animación determina cuánta fuerza se aplica en función de la compresión del resorte y crea un resultado cercano al objetivo, que tendría un poco más de oscilación en el tercer rebote. Puedes comparar la suspensión creada con una curva de animación con la del controlador PID, usando el PID en Hover Racer Live 7/21 Cycle 4.2de Unity. La única diferencia es que el resultado PID se multiplica por la fuerza de desplazamiento en lugar del valor Y de la curva de animación.

Después de implementar el PID y mucho equilibrio, la suspensión del vehículo se siente más cerca del objetivo, con menos oscilación de seguimiento y menos resistencia necesaria para la supresión. Desafortunadamente, el PID debe equilibrarse para cada vehículo si tienen diferentes valores de masa, lo que lleva mucho tiempo. Para fines de creación de prototipos, esto se puede hacer de forma rápida y visual con Curvas de animación, y se pueden analizar los resultados trazados del movimiento. Para evaluar la implementación de PID, nuevamente, puede usar una curva para trazar el resultado en una curva en blanco. El resultado es mucho mejor, con un segundo rebote ligeramente exagerado, pero que proporciona el movimiento y la apariencia que desea para una camioneta grande y flotante.

Una camioneta blanca sin ruedas suspendida en el aire, en Unity
La implementación final de la suspensión del vehículo utilizando PID, pero basada en las curvas de animación desarrolladas durante el prototipado: La suspensión sigue siendo exagerada, utilizándose longitudes de resorte de 1 metro.
Una curva de amortiguación objetivo a la izquierda, con una curva de resultado trazada a la derecha
Vea el resultado de la curva de amortiguación objetivo de Alexis Bacot a la izquierda, y el resultado trazado del movimiento del vehículo después de implementar el PID a la derecha.

Para resumir, utilice curvas de animación al desarrollar el movimiento del vehículo para:

  • Grafique la salida de potencia del motor de un vehículo y produzca una progresión de potencia suave.
  • Cree movimientos de frenado realistas, como cuando la fuerza de frenado se aplica rápidamente y luego se reduce con el tiempo para simular el frenado de un automóvil real; o, en un juego como iRacing, donde el conductor frena en el límite de los neumáticos para que el automóvil disminuya la velocidad en un corto período de tiempo sin perder el control.
  • Simular un sistema de suspensión que proporciona fuerzas ascendentes al automóvil.
  • Simule la tracción lateral, con cálculos de contrafuerza lateral que evitan que el automóvil se deslice demasiado hacia la izquierda o la derecha.
  • Simular la dirección al utilizar un controlador (la dirección se puede utilizar cerca del medio, alrededor de -0,5 a 0,5, pero se vuelve progresivamente más rápida cuando la posición del joystick se acerca a -1 o 1).
Un bloque verde flotando en agua azul, rodeado de montañas, en Unity
En este prototipo, se utiliza curve.Evaluate(time) para mover la Transformación de la plataforma en el eje Y a lo largo del tiempo.

Además de la física del vehículo, las curvas de animación se pueden utilizar como palancas de diseño para crear prototipos del movimiento del jugador, el daño del impacto a lo largo del tiempo y más. Como una poderosa herramienta de creación de prototipos, las Curvas de animación permiten a los diseñadores de juegos probar la aplicación de fuerzas variables e identificar la “sensación” correcta para la mecánica, sin tener que escribir algoritmos complejos o cálculos físicos.

Para obtener más orientación e inspiración, consulta el Manual del diseñador de juegos, disponible para descargar de forma gratuita.