Animation Curves, la palanca de diseño definitiva
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 al libro de jugadas del diseñador de juegos de Unity , una guía detallada de más de 100 páginas que instruye a los diseñadores de juegos sobre cómo crear prototipos, crear y probar el juego en Unity. Los enlaces a las publicaciones de blog anteriores de Christo se incluyen al final de este artículo.
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 al libro de jugadas del diseñador de juegos de Unity , una guía detallada de más de 100 páginas que instruye a los diseñadores de juegos sobre cómo crear prototipos, crear y probar el juego en Unity. Los enlaces a las publicaciones de blog anteriores de Christo se incluyen al final de este artículo.
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 uno de esos tipos de componentes que ofrecen a los diseñadores y creadores de juegos posibilidades interesantes, especialmente al crear prototipos. Úselos en su proyecto, por ejemplo, dentro de un sistema de partículas para controlar las 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 usa curvas en una variedad de contextos diferentes, específicamente en animación. Los editores de curvas tienen varias opciones y herramientas diferentes que puede aprovechar.
Esta publicación se centrará en trabajar con Animation Curves a través de la API de Unity, con el tipo de variable AnimationCurve . De esta manera, se pueden utilizar para capturar y almacenar datos, lo que es útil para analizar los resultados. Las curvas también son compatibles con ScriptableObjects, que, como se explica en el libro de jugadas , son excelentes para editar datos de 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.
Puede agregar claves, alterar sus tangentes y manipular los controladores en la curva para encontrar la forma que brindará los resultados deseados.
Una palanca de diseño visual como Animation Curve hace posible que los diseñadores de juegos perfeccionen el juego sin tener que escribir matemáticas complejas o funciones de aceleración .
Una forma de usar las 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 automóvil. La acción comienza con un tambaleo cuando la mano agarra la palanca para cerrar la puerta. La puerta se cierra lentamente al principio, pero el movimiento se acelera a medida que la puerta se cierra y luego termina con una parada abrupta; tal vez con un pequeño rebote o clic. Todos estos movimientos se pueden guardar dentro de la misma curva para la secuencia.
Como muestra este ejemplo, las curvas de animación son beneficiosas para cambiar las propiedades de un objeto con el tiempo para crear un movimiento de aspecto natural. Otros casos de uso se centran en cómo un objeto se mueve o gira, un personaje acelera o desacelera al entrar o salir de un sprint, o un motor entrega energía al controlador de un automóvil.
Cuando crea una Curva de animación para editar en el Inspector, podrá 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 usa el eje X para el tiempo.
Examinemos cómo podría usar una curva de animación para controlar la potencia de salida del motor de un vehículo. Puede crear una "pseudo" curva de par motor para devolver la fuerza aplicada al vehículo en función de las RPM actuales del motor (revoluciones por minuto). 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, puede "normalizar" o establecer las RPM entre 0 y 1. Las curvas de "par" que cree se pueden guardar y reutilizar para otros vehículos y marchas.
Establezca este valor dividiendo su valor bruto o actual por el valor máximo:
RPM actual normalizado = RPM actual / RPM máximo
La potencia de salida (eje Y) también se utilizará entre 0 y 1 para mantener el editor de curvas manejable y las propias curvas reutilizables. Este valor se puede agregar a la fuerza de movimiento del vehículo, para mover el cuerpo rígido del vehículo hacia adelante en el eje Z.
Puede crear varios resultados con la misma configuración para otros vehículos manteniéndose entre los valores de 0,0 y 1,1 en la curva.
Agregar una ecuación básica de relación de transmisión al motor de su automóvil puede dar como resultado vehículos de aspecto realista que se mueven y balancean a medida que cambia de marcha 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 las 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 cargadas y descargadas de sus curvas, e intercambiar estas curvas en tiempo de ejecución para que el vehículo conduzca de la manera que desee.
Aunque no usará esto con frecuencia, puede 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 da más control sobre la modificación de sus curvas, lo que también puede incluir suavizar las tangentes según sea necesario.
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, puede agregar potencia con el tiempo al acelerar con la curva que se muestra arriba (que representa la "pseudo" caja de cambios) para crear la sensación de que el automóvil cambia de marcha, ajustando su tono hacia arriba a medida que se entrega la potencia y luego hacia abajo. nuevamente a medida que la potencia se apaga en la parte superior de cada engranaje. Esto es ideal para crear prototipos del movimiento de un vehículo colocando toda la potencia del automóvil en una curva que mapea todos los engranajes, desde el inicio de la primera velocidad en x0, y0 hasta la parte superior de la quinta velocidad en x1, y1.
Las RPM generalmente se acumulan con el tiempo al acelerar, por lo que esencialmente está trazando valores a lo largo del tiempo, de manera 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 libro de jugadas del diseñador de juegos .
Tomemos otro ejemplo; la suspensión y el movimiento de un automóvil cuando se conduce sobre un terreno irregular, en las esquinas o cuando se entrega potencia a las ruedas. Se puede gestionar una mejor dirección, el control de las fuerzas laterales o el deslizamiento de los neumáticos con las curvas de animación para crear resultados realistas que puede refinar visualmente.
Al crear una mecánica basada 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 hacia arriba aplicada en cada rayo y un controlador PID (proporcional-integral-derivado). algoritmo para controlar el rebote, o en algunos casos, la ley de Hooke para la amortiguación. Se puede ver un ejemplo de esto en el ciclo 4.2 de Hover Racer Live 7/21 de Unity , junto con un ejemplo más abajo en esta publicación que usa 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 receptiva. 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), puede usarse como una alternativa a la ley de Hooke. Un PID en 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.
- Controlar la precisión que tienen los agentes de IA enemigos cuando disparan a tus jugadores, mientras evitan ser golpeados.
- Predicción de latencia en juegos multijugador.
Los PID se pueden usar en cualquier parte del desarrollo de juegos, especialmente en entornos limitados y simulaciones que requieren un " control automático preciso y optimizado ". Kerbal Space Program by Squad usa PID para mantener una nave espacial en una sola dirección.
Según este estudio , “la regulación PID es la tecnología de sistemas continuos más madura y más utilizada” fuera del desarrollo de juegos. Consulte esta lección sobre el sistema de control: Introducción al control PID para obtener información adicional.
Es posible que los algoritmos del controlador PID no tomen mucho tiempo para crearse, pero requieren tiempo para equilibrarse; tiempo que se multiplica dependiendo de cuantos vehículos tengas. Sin embargo, al crear prototipos, puede usar 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 final).
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. Cuando se trata de espacio, esto es "matemáticamente perfecto" en un motor de juego, sin fuerzas de movimiento opuestas a menos que se agreguen o que la gravedad predeterminada esté habilitada. Por lo tanto, a menudo es más fácil usar una curva simple para controlar el cambio y obtener buenos resultados.
En el caso de crear la suspensión para un vehículo, puede usar Curvas de animación para informar cuánta fuerza opuesta se aplica según el nivel de compresión del resorte (normalizado entre 0 y 1), en lugar de usar un controlador PID para crear amortiguación. Combinado con un Rigidbody y una pequeña cantidad de arrastre, se suprime la oscilación de rebote y la suspensión del vehículo reacciona al aumento o 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á de 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 utilícelo en AddForceAtPosition para aplicar la fuerza hacia arriba en cada punto de un ciclo, según el número de puntos de suspensión. No se necesitan fuerzas descendentes adicionales además de la gravedad predeterminada de Unity en -9.81f.
Aquí está la fórmula:
fuerza hacia arriba = multiplicador de fuerza * curva de fuerza. Evaluar (compresión de resorte normalizada);
rigidBody.AddForceAtPosition(hitNormal * upsForce, point.transform.position);
Usando una relación masa: fuerza de 13:110 y la siguiente curva.
El vehículo se asienta con una compresión de aproximadamente el 50 % 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 deje caer desde una altura extremadamente alta o que el jugador lo sobrecargue agregando masa.
Para encontrar buenos valores, comience con una curva y = b^x (que se parece a un cuarto de círculo). Mantenga el arrastre bajo y ajuste la masa del vehículo a lo que es en realidad. Luego, la fuerza hacia arriba se ajusta hasta que el vehículo se asiente con una compresión del resorte de aproximadamente el 50 %. Deje caer el vehículo varias veces para verificar 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 conducen sobre terreno irregular, donde cada punto de tracción se puede ganar o perder, lo convierte en 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, furgonetas 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 acelerar y frenar. Las curvas se pueden usar en combinación con los sistemas existentes si aún no está usando el sistema Rigidbody de Unity o su propio método de suspensión. Puede usar las curvas para la dirección o para amplificar la potencia del motor, la suspensión, la resistencia al avance, el deslizamiento de las llantas, la fuerza de frenado y más. Las curvas de animación son una herramienta tan ú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.
La fila de esferas en la imagen de arriba se creó colocando una secuencia de cuerpos rígidos en una fila y restringiendo sus propiedades de posición de congelación X y Z. Luego se aplicó una fuerza hacia arriba utilizando una Curva de Animación basada en la fuerza de compresión hacia arriba, pero con diferentes curvas para cada esfera, colocadas una al lado de la otra para una mejor visualización. Puede usar 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 ayudarlo a crear abstracciones de funciones más complejas.
Las curvas son un poderoso tipo de datos de gráfico XY y, aunque no son técnicamente perfectos, pueden ayudarlo a crear prototipos de soluciones de amortiguación rápida que se pueden editar visualmente en el Inspector y guardar 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 interfaz de usuario y mucho más... ¡se usa en todas partes! Comprender la amortiguación es clave para lograr un gran 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, y cómo reacciona con precisión al cambio del 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 bolas falsas", un ejemplo en el que las curvas de animación brindan una poderosa ventaja.
Por supuesto, las curvas tienen más usos que un tipo de datos XY para manipular el juego. También se pueden tratar como una herramienta de evaluación para capturar datos visualmente usando 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, use 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.1s, se agrega una clave a la curva. Vea el mini resultado en el Inspector o abra el gráfico para ver los datos completos.
Echemos un último vistazo a la furgoneta que cae. La curva de animación dicta 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. Puede comparar la suspensión creada con una curva de animación con la del controlador PID, utilizando el PID en Hover Racer Live 7/21 Cycle 4.2 de Unity . La única diferencia es que el resultado de 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 arrastre y menos arrastre necesario 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 las 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 proporcionando el movimiento y la apariencia que desea para una camioneta grande y flotante.
Para recapitular, use Curvas de animación cuando desarrolle el movimiento del vehículo para:
- Trace la salida de la potencia del motor de un vehículo y produzca una progresión de potencia uniforme.
- 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 la llanta para que el automóvil disminuya la velocidad en un corto período de tiempo sin perder el control.
- Simule un sistema de suspensión que proporciona las fuerzas ascendentes para el 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 hacia la derecha.
- Simule la dirección cuando use un controlador (la dirección se puede usar cerca del medio, alrededor de -0.5 a 0.5, pero se vuelve progresivamente más rápida cuando la posición de la palanca se acerca a -1 o 1).
Además de la física del vehículo, las curvas de animación se pueden usar como palancas de diseño para crear prototipos del movimiento del jugador, daños por golpes a lo largo del tiempo y más. Como una poderosa herramienta de creación de prototipos, Animation Curves permite a los diseñadores de juegos probar la aplicación de fuerza variable e identificar la "sensación" correcta para la mecánica, sin tener que escribir algoritmos complejos o cálculos físicos.