Animation Curves, a melhor alavanca de design

Esta é a terceira postagem do blog de Christo Nobbs em sua série para designers de jogos. A série expande suas contribuições para The Unity game designer playbookum guia detalhado de mais de 100 páginas que instrui os designers de jogos sobre como criar protótipos, criar e testar a jogabilidade no Unity. Os links para as postagens anteriores do blog de Christo estão incluídos no final deste artigo.
Em Unity, há vários "tipos" que podemos usar para armazenar dados que são tão benéficos quanto alavancas de design para sistemas de balanceamento, jogabilidade, configurações de personagens, perfis de veículos e assim por diante. As curvas de animação são um tipo de componente que oferece aos designers e criadores de jogos possibilidades interessantes, especialmente durante a criação de protótipos. Use-os em seu projeto, por exemplo, dentro de um sistema de partículas para controlar variáveis animadas ou dentro do componente de fonte de áudio para gerenciar a atenuação e outras propriedades.
Uma curva é um gráfico de linhas que mostra a resposta (no eixo Y) ao valor variável de uma entrada (no eixo X). A Unity usa curvas em uma variedade de contextos diferentes, especificamente em animação. Os Curve Editors têm várias opções e ferramentas diferentes que podem ser aproveitadas.
Esta postagem se concentrará no trabalho com curvas de animação por meio da API do Unity, com o tipo de variável AnimationCurve. Dessa forma, eles podem ser usados para capturar e armazenar dados, o que é útil para analisar os resultados. As curvas também são compatíveis com ScriptableObjects, que, conforme discutido no manual, são ótimos para editar dados de jogabilidade.
As curvas de animação podem ser editadas no Inspector como variáveis públicas ou quando serializadas. Você pode salvar, exportar ou carregá-los no modo Editar ou em tempo de execução. As tangentes editáveis permitem controlar a forma da curva entre as teclas.


Você pode adicionar chaves, alterar suas tangentes e manipular alças na curva para encontrar a forma que produzirá os resultados desejados.

Uma alavanca de design visual, como a Animation Curve, permite que os designers de jogos aprimorem a jogabilidade sem precisar escrever funções matemáticas ou de facilitação complexas.
Uma maneira de usar as curvas de animação é em uma Timeline, para adicionar nuances e detalhes aos movimentos lineares. Veja o exemplo de um personagem fechando a porta de um carro. A ação começa com uma oscilação quando a mão agarra a alavanca para fechar a porta. A porta se fecha lentamente no início, mas o movimento se acelera à medida que a porta se fecha e termina com uma parada abrupta, talvez com um pequeno salto ou clique. Todos esses movimentos podem ser salvos na mesma curva da sequência.



Como mostra este exemplo, as Curvas de animação são úteis para alterar as propriedades de um objeto ao longo do tempo para criar um movimento de aparência natural. Outros casos de uso se concentram em como um objeto se move ou gira, um personagem acelera ou desacelera para entrar ou sair de uma corrida, ou um motor fornece energia a um controlador de carro.

Ao criar uma Curva de animação para editar no Inspector, você poderá avaliar a curva passando um parâmetro, chamado de tempo no Unity. Mais adiante nesta publicação, veremos por que a posição é mais descritiva quando não se usa o eixo X para o tempo.
Vamos examinar como você poderia usar uma Curva de Animação para controlar a potência do motor de um veículo. Você pode criar uma "pseudo" curva de torque do motor para retornar a força aplicada ao veículo com base na RPM (rotações por minuto) atual do motor. Isso aumenta com o tempo se o jogador pressionar o acelerador.
Em vez de mapear a faixa completa de RPM para cada marcha e veículo, você pode "normalizar" ou definir o RPM entre 0 e 1. As curvas de "torque" criadas podem ser salvas e reutilizadas em outros veículos e engrenagens.
Defina esse valor dividindo seu valor bruto ou atual pelo valor máximo:
normalisedCurrentRPM = currentRPM / maxRPM
A potência de saída (eixo Y) também será usada entre 0 e 1 para manter o Curve Editor gerenciável e as próprias curvas reutilizáveis. Esse valor pode ser adicionado à força de movimento do veículo, para mover o Rigidbody do veículo para frente no eixo Z.

Você pode criar vários resultados com a mesma configuração para outros veículos, mantendo-se entre os valores de 0,0 e 1,1 na curva.

Adicionar uma equação básica de relação de marchas ao motor do seu carro pode resultar em veículos de aparência realista que se movem e balançam à medida que você passa pelas marchas e atinge diferentes curvas de potência, ou a mesma curva em diferentes pontos. Isso exige que o carro seja um Rigidbody. Ao adicionar outros Rigidbodies no porta-malas ou nos assentos traseiros do carro, o carro terá um movimento impactado, o que pode ser divertido para missões de entrega cronometradas.
Se não quiser usar o sistema de física da Unity porque tem um controlador de carro personalizado, você pode criar variantes sem carga e com carga das suas curvas e trocar essas curvas em tempo de execução para que o veículo dirija da maneira que você deseja.
Embora isso não seja usado com frequência, você pode adicionar chaves, modificar chaves (o que remove e adiciona novas chaves) e remover chaves inteiramente nas curvas em tempo de execução por meio da API do Unity. Isso lhe dá mais controle sobre a modificação das curvas, o que também pode incluir a suavização de tangentes, conforme necessário.



As curvas de animação permitem que você crie excelentes abstrações de sistemas mais complexos que podem ser controlados em um formato visual. No exemplo do motor, é possível adicionar potência ao longo do tempo ao acelerar com a curva mostrada acima (que representa a "pseudo" caixa de câmbio) para criar a sensação de que o carro está trocando de marcha, ajustando a inclinação para cima à medida que a potência é fornecida e, em seguida, para baixo novamente à medida que a potência diminui no topo de cada marcha. Isso é ideal para criar um protótipo do movimento de um veículo, colocando toda a potência do carro em uma curva que mapeia todas as marchas, desde o início da primeira marcha em x0,y0 até o topo da quinta marcha em x1,y1.
As RPM geralmente se acumulam ao longo do tempo durante a aceleração, portanto, basicamente, você está plotando valores ao longo do tempo, como se estivesse adicionando movimento linear a um objeto em movimento. Leia mais sobre isso na seção sobre tempo e animação no Manual do designer de jogos.

Vejamos outro exemplo: a suspensão e o movimento de um carro quando ele trafega em terrenos irregulares, em curvas ou quando a potência é fornecida às rodas. Melhor direção, controle de forças laterais ou deslizamento de pneus podem ser gerenciados com o Animation Curves para criar resultados realistas que podem ser refinados visualmente.
Ao criar uma mecânica baseada em raycast para um veículo, seja um veículo flutuante ou com rodas, uma opção comum para criar o efeito de "suspensão" no motor é uma força para cima aplicada em cada raio e um algoritmo de controlador PID (proporcional-integral-derivativo) para controlar o salto ou, em alguns casos, a lei de Hooke para amortecimento. Um exemplo disso pode ser visto no Hover Racer Live 7/21 Cycle 4.2 da Unity, juntamente com um exemplo mais abaixo nesta postagem que usa um PID baseado nele.
Um algoritmo de controlador PID é um mecanismo de feedback de loop de controle, ou um controlador, usado em muitos setores, inclusive no desenvolvimento de jogos, quando é necessária uma correção responsiva. O controlador PID calcula um valor de erro como a diferença entre uma variável de processo medida e um ponto de ajuste desejado e, em relação à elasticidade (ou ao nosso exemplo dado), ele pode ser usado como uma alternativa à lei de Hooke. Um PID em jogos também é prático para:
- Fazer com que um veículo regule uma velocidade-alvo no modo de controle de cruzeiro e, ao mesmo tempo, esteja sujeito de forma imprevisível a outros fatores, como massa transportada, entrada do jogador ou angulação do terreno.
- Controle da precisão dos agentes de IA inimigos ao atirar de volta nos jogadores, evitando que eles sejam atingidos.
- Previsão de latência em jogos Multiplay.
Os PIDs podem ser usados em qualquer lugar no desenvolvimento de jogos, especialmente em sandboxes e simulações que exigem "controle automático preciso e otimizado". O Kerbal Space Program da Squad usa o PID para manter uma nave espacial em uma única direção.
De acordo com esse estudo, "a regulação PID é a tecnologia de sistemas contínuos mais madura e amplamente utilizada" fora do desenvolvimento de jogos. Veja esta palestra sobre o sistema de controle : Introdução ao controle PID para obter informações adicionais.

Os algoritmos do controlador PID podem não levar muito tempo para serem criados, mas exigem tempo para serem balanceados; tempo que é multiplicado dependendo de quantos veículos você tem. No entanto, durante a criação de protótipos, você pode usar uma Curva de Animação para economizar tempo ou evitar os desafios técnicos de implementar e equilibrar vários controladores PID (eventualmente, você desejará substituir a solução de curva por um PID para obter o controle máximo).
As curvas são ideais para prototipagem porque podem ser usadas para corresponder visualmente a exemplos de referência de alvos do mundo real. No que se refere ao espaço, isso é "matematicamente perfeito" em um mecanismo de jogo, sem forças de movimento opostas, a menos que sejam adicionadas ou que a gravidade padrão esteja ativada. Portanto, muitas vezes é mais fácil usar uma curva simples para controlar a mudança e yield resultados sólidos.
No caso da criação de suspensão para um veículo, você pode usar Animation Curves para informar quanta força oposta é aplicada com base no nível de compressão da mola (normalizada entre 0 e 1), em vez de usar um controlador PID para criar o amortecimento. Combinado com uma carroceria rígida e uma pequena quantidade de arrasto, a oscilação do ressalto é suprimida e a suspensão do veículo reage ao aumento ou à diminuição da carga.
Para determinar a compressão da mola, você precisa subtrair a distância de acerto do raio do comprimento da mola de 1,0f. Independentemente de seu comprimento, quando a mola estiver com 25% de compressão, o valor da compressão será 0,25. Defina esse valor de compressão como o valor X na Curva de animação, multiplique-o pela força de mola desejada (porque você está trabalhando com valores normalizados) e, em seguida, use-o em AddForceAtPosition para aplicar a força ascendente em cada ponto de um loop, com base no número de pontos de suspensão. Não são necessárias forças descendentes adicionais além da gravidade padrão da Unity a -9,81f.
Aqui está a fórmula:
upwardsForce = forceMultiplier * forceCurve.Evaluate(springCompressionNormalized);
rigidBody.AddForceAtPosition(hitNormal * upwardsForce, point.transform.position);
Usando uma relação massa:força de 13:110 e a curva abaixo.


O veículo se estabiliza com aproximadamente 50% de compressão usando valores adequados de massa, força ascendente e pequenas quantidades de arrasto linear e angular para suprimir a oscilação. Isso permite que o veículo salte e se acomode, mas não caia, a menos que seja derrubado de uma altura extremamente alta ou sobrecarregado pelo jogador que adiciona massa.
Para encontrar bons valores, comece com uma curva y = b^x (que se assemelha a um quarto de círculo). Mantenha o arrasto baixo e defina a massa do veículo de acordo com a realidade. A força de subida é então ajustada até que o veículo fique com aproximadamente 50% de compressão da mola. Deixe o veículo cair algumas vezes para verificar se ele está no fundo do poço e veja onde ele se assenta após o salto. O uso dessa abordagem para a suspensão de veículos que trafegam em terrenos irregulares, onde cada ponto de tração pode ser ganho ou perdido, proporciona um sistema de suspensão rápido e controlável.
O uso de Animation Curves (curvas de animação) para o modelo de suspensão pode garantir movimentos variados para veículos - carros, vans ou caminhões com suspensão ruim -, ou seja, aqueles que ficam no fundo do poço o tempo todo, saltam como nos jogos de fliperama ou rolam nas curvas e balançam quando você acelera e freia. As curvas podem ser usadas em combinação com sistemas existentes se você ainda não estiver usando o sistema Rigidbody da Unity ou seu próprio método de suspensão. É possível usar curvas para a direção ou para ampliar a potência do motor, a suspensão, o arrasto, a derrapagem dos pneus, a força de frenagem e muito mais. As Animation Curves são uma ferramenta muito útil e versátil no Unity para adicionar alavancas de design a cada veículo e controlar suas características visualmente no Inspector.



A fileira de esferas na imagem acima foi criada posicionando uma sequência de Rigidbodies em uma fileira e restringindo suas propriedades X e Z Freeze Position. Uma força para cima foi então aplicada usando uma Curva de Animação baseada na força de compressão para cima, mas com curvas diferentes para cada esfera, posicionadas lado a lado para melhor visualização. Você pode usar essa técnica para encontrar o nível desejado de ressalto para um objeto ou para ajustar o ressalto existente para equilibrar as características. Como designer, a capacidade de manipular as características da força ascendente pode ajudá-lo a criar abstrações de funções mais complexas.
As curvas são um tipo de dados de gráfico XY avançado e, embora não sejam tecnicamente perfeitas, podem ajudá-lo a criar protótipos de soluções de amortecimento rápidas que podem ser editadas visualmente no Inspector e salvas como predefinições em tempo de execução. Neste blog sobre a arte do amortecimento, Alexis Bacot destaca todos os aspectos que "dependem de um bom amortecimento". Câmera, animação, movimento, gradientes de cor, transições de interface do usuário e muito mais... ele é usado em todos os lugares! Entender o amortecimento é fundamental para obter um ótimo polimento. O amortecimento, por si só, pode fazer a diferença entre uma experiência boa ou ruim."
Na mesma postagem, ele demonstra como o SmoothDamp da Unity pode ser usado para criar uma bela facilidade de entrada e saída, e reage à mudança do alvo com precisão. Mas ele não salta como um "amortecedor de mola avançado que pode oscilar, o que é ótimo para suspensão de carro ou física de bola falsa" - um exemplo de como as curvas de animação oferecem uma vantagem poderosa.
É claro que as curvas têm mais usos do que como um tipo de dados XY para manipular a jogabilidade. Eles também podem ser tratados como uma ferramenta de avaliação para capturar dados visualmente usando o AddKey por meio da API do Unity. Para avaliar uma posição ao longo do tempo, como o amortecimento no exemplo da suspensão do veículo ou as esferas em queda, use AddKey(elapsedTime, currentSpringCompression) em um método e, em seguida, chame esse método e passe captureResolution como a taxa de repetição por meio de InvokeRepeating. Uma resolução de captura de 0,1f significa que, a cada 0,1s, uma chave é adicionada à curva. Visualize o mini resultado no Inspector ou abra o gráfico para ver os dados completos.


Vamos dar uma última olhada na van em queda. A Curva de animação determina quanta força é aplicada com base na compressão da mola e cria um resultado próximo ao alvo, que teria um pouco mais de oscilação no terceiro salto. Você pode comparar a suspensão criada com uma Curva de animação com a do controlador PID, usando o PID no Hover Racer Live 7/21 Cycle 4.2 da Unity. A única diferença é que o resultado do PID é multiplicado pela força de pairar em vez do valor Y da Curva de animação.
Após a implementação do PID e de muito balanceamento, a suspensão do veículo parece mais próxima do objetivo, com menos oscilação na traseira e menos arrasto necessário para a supressão. Infelizmente, o PID precisa ser balanceado para cada veículo se eles tiverem valores de massa diferentes, o que leva muito tempo. Para fins de prototipagem, isso pode ser feito de forma rápida e visual com o Animation Curves, e os resultados plotados do movimento podem ser analisados. Para avaliar a implementação do PID, novamente, você pode usar uma curva para plotar o resultado em uma curva em branco. O resultado é muito melhor, com um segundo salto ligeiramente exagerado, mas proporcionando o movimento e a aparência que você deseja para uma grande van flutuante.


Recapitulando, use as Curvas de Animação ao desenvolver o movimento do veículo:
- Plote a saída da potência do motor de um veículo e produza uma progressão suave da potência.
- Crie movimentos de frenagem realistas, como quando a força de frenagem é aplicada rapidamente e depois reduzida ao longo do tempo para simular a frenagem de um carro real; ou, em um jogo como o iRacing, quando o motorista freia no limite dos pneus para que o carro diminua a velocidade em um curto espaço de tempo sem sair do controle.
- Simule um sistema de suspensão que forneça as forças de subida para o carro.
- Simule a tração lateral, com cálculos de contraforça lateral que evitam que o carro deslize muito para a esquerda ou para a direita.
- Simule a direção ao usar um controle (a direção pode ser usada perto do meio, em torno de -0,5 a 0,5, mas fica progressivamente mais rápida quando a posição do manche se aproxima de -1 ou 1).

Além da física do veículo, as curvas de animação podem ser usadas como alavancas de design para a criação de protótipos do movimento do jogador, danos causados ao longo do tempo e muito mais. Como uma poderosa ferramenta de prototipagem, as Curvas de Animação permitem que os designers de jogos testem a aplicação de forças variáveis e identifiquem a "sensação" certa para a mecânica, sem precisar escrever algoritmos complexos ou cálculos de física.
Para obter mais orientação e inspiração, confira o Game Designer Playbook, disponível para download gratuito.
