Gráfico de estado animado

Oi Nós da Playrix decidimos fazer o nosso Unity3D . E existe o Animator. Neste artigo, mostrarei como fizemos em casa e como funciona.


Quando começamos a projetar a arquitetura de nossos gráficos de animação, é claro que analisamos outros análogos, em particular no Unity Animator. No entanto, queríamos criar uma solução mais universal. Ao contrário da mesma unidade, temos a personalização dos estados de animação por meio da interface do controlador. Mas primeiro, vale a pena descobrir o que é um gráfico de estado animado. Se você já encontrou isso, faz sentido pular a parte introdutória e seguir para os recursos de implementação.

Então, o que exatamente é esse gráfico de estado animado?



Um gráfico de estado de animação permite representar graficamente transições entre diferentes estados de animação.

Tomemos, por exemplo, animação de personagem:


Temos um modelo tridimensional de um homem e existem várias de suas animações:

  • ocioso - fica parado;
  • andar - avança;
  • sentado
  • Olá - acena com a mão.

A abordagem clássica para gerenciar animações é a seguinte: se você deseja que o objeto fique em pé - ative o modo inativo, ande - ande, sente - se. Mas há certas dificuldades com isso.

Primeiro, você precisa controlar manualmente a duração e a sequência das animações. Por exemplo, para uma pessoa se sentar, primeiro você precisa reproduzir a animação, como ela se senta e depois começar a reproduzir a animação em loop, onde a pessoa já está sentada. Personalizar as junções dessas animações no código é difícil e inconveniente.

Em segundo lugar, as articulações entre as animações tornam-se visíveis se os fins da animação não coincidirem, ou precisamos incluir outra animação no meio da atual. Nesse caso, é simplesmente impossível combinar as animações perfeitamente. Lembre-se dos jogos antigos, onde as animações de personagens mudavam instantaneamente.

O gráfico de animação foi projetado para resolver esses problemas. Com ele, você não precisa operar animações manualmente, agora você opera com estados. Como um objeto será animado para atingir esse estado é o trabalho de animadores e designers. Agora o programador não pensa no tempo e na sequência da animação, apenas indica em que estado o objeto deve entrar.

Além disso, com o gráfico de animação, o problema de juntar animações desaparece. Na transição entre estados, podemos fazer uma transição suave de uma animação para outra. Isso é feito usando pesos. O peso é um fator de mistura de 0 a 1, em que 0 significa que a animação não afeta o objeto de forma alguma e 1 o afeta completamente.

Por exemplo, a transição entre caminhar (inativo) e em pé (inativo) é muito exigente na configuração do processo. A qualquer momento da animação, o personagem pode parar. Portanto, a transição não é realizada instantaneamente, mas por um pequeno período de tempo. Nesse momento, o peso da marcha diminui de 1 para 0 e o peso em pé aumenta de 0 para 1. É importante que a soma dos pesos seja igual a um, caso contrário, artefatos podem aparecer.

Como tudo isso funciona?



Um gráfico consiste em estados e transições. Um estado é um conjunto de controladores de animação, cada um dos quais pode reproduzir algum tipo de animação em um objeto ou executar algum tipo de lógica. O controlador possui pontos de entrada e saída - esses são os momentos em que o gráfico liga o estado com este controlador e o desliga de acordo. O controlador também possui uma função de atualização, na qual, além do intervalo de tempo do último quadro, o peso da transição ocorre. Para misturar animações, isso deve ser levado em consideração.

Os controladores têm uma única interface. Além disso, os desenvolvedores podem adicionar seus controladores. Por exemplo, você pode criar um controlador que execute algum tipo de lógica ou defina texto em um pop-up, etc. Essa personalização simples permite que você use o gráfico de animação com muita flexibilidade.

Nós também temos variáveis. Essas variáveis ​​podem ser definidas externamente, inclusive do código, e depois lê-las nos controladores. Assim, por exemplo, você pode alternar algum tipo de animação para um personagem no mesmo estado. Em geral, você pode até repetir o paradigma de transição entre estados por meio de variáveis ​​e condições, como o Unity. Em conjunto com controladores personalizáveis, é bastante conveniente.

Transições podem ser qualquer número. Muitas transições podem entrar em estado e sair da mesma maneira ilimitadamente. As transições determinam a possibilidade de alcançar estados. Por exemplo, se não houver transição diretamente entre os estados A e F, mas houver uma cadeia A → B → C → D → E → F, quando você solicitar uma transição de A para F, o próprio gráfico entenderá que precisa passar pelos estados intermediários B, C, D e E.


As transições têm configurações e durações de intervalo de início. Com a duração, tudo é simples - esse é o momento em que a transição será feita. Mas o intervalo já é mais complicado: determina o período de tempo aceitável para a animação em que a transição pode ser iniciada.

Por exemplo, para que um personagem se sente, primeiro você precisa reproduzir a animação enquanto ele se senta e depois iniciar a animação de assentos. Nesse caso, o intervalo de transição de "senta-se" para "senta-se" deve ser "sentado" no final da animação, para que possamos ver como ela se senta e, no final, rápida e suavemente, entre na animação da cadeira.

Outro exemplo: um personagem está andando e ele precisa parar. Nesse caso, o intervalo de início da transição deve ser o comprimento inteiro da animação, porque o personagem pode parar a qualquer momento.

O gráfico de animação faz todo o trabalho relacionado:

  • planeja um caminho para o estado necessário;
  • Atualiza os estados em execução no momento
  • faz uma transição suave entre estados;
  • ajusta os pesos neles.

Funcionalidades interessantes


Existem muitos tipos diferentes de animações no mecanismo Playrix: modelos 3D, coluna, flash, efeitos de partículas, animação esquelética. Cada tipo tem um controlador específico.

Além de controladores de animação simples, temos vários auxiliares. Por exemplo, um controlador aleatório. Pode incluir uma lista de outros controladores e a probabilidade de sua escolha. Cada vez que um objeto entra em um estado com um controlador aleatório, a seleção aleatória ocorre levando em consideração as probabilidades e o controlador selecionado começa a funcionar. O resto está dormindo e inativo, esperando o momento.

Mas, às vezes, em um estado, precisamos alternar animações. Por exemplo, se vários caracteres tiverem o mesmo gráfico e todos tiverem algum tipo de animação de ação. Um personagem precisa pegar sua vassoura e começar sua vingança, outro para pegar sua câmera e começar a tirar fotos, o terceiro está tomando sorvete. Para tais situações, existe um controlador especial, que também contém uma lista de controladores, mas, diferentemente dos randomizados, aqui ele seleciona um controlador, dependendo da variável.

As variáveis ​​são definidas no gráfico e podem ser alteradas externamente, por exemplo, a partir do código. Neste exemplo, um tipo de sequência é usado e cada tipo de ação corresponde a um determinado valor da variável. Quando um personagem é criado no jogo, essa variável é definida para ele, dependendo do comportamento desejado.

Também temos um controlador que pode misturar várias animações. Por exemplo, você pode misturar animações a pé, esquerda, direita e avanço. Assim, nas curvas, você pode ajustar os pesos entre eles para que as pernas do personagem não escorregem e a caminhada pareça natural.

Precisamos ir mais fundo



Há muitas vantagens no fato de fazermos a nossa unidade. Uma delas é que podemos fazer o que queremos e o que queremos. E queríamos uma oportunidade ilimitada para expandir o gráfico de animação.

Temos uma interface de controlador, existem vários controladores "prontos para uso" e existe a capacidade de implementar a interface e fazer qualquer coisa nela (e não necessariamente uma animação):

  • mude o texto no botão;
  • interagir com outros objetos na hierarquia;
  • e até gerenciar outro gráfico de animação.

Usamos essa abordagem em visitantes do zoológico no jogo Wildscapes. Cada visitante possui dois gráficos: um para animar o modelo e outro para animar o comportamento.

O primeiro gráfico é bastante simples, controla a caminhada, pode reproduzir algumas animações de personagens separadas.

O segundo gráfico é muito mais complicado e apresenta alguns cenários de comportamento. Por exemplo, primeiro o personagem vai, depois senta em um banco, cumprimenta alguém, tira fotos e continua. Este é um ramo de estado separado.

Essa lógica pode ser colocada na primeira coluna, mas as animações serão duplicadas várias vezes. Mas com dois gráficos, tudo é muito mais simples. O gráfico de controle contém uma cadeia de estados, incluindo estados do primeiro gráfico, que são executados em paralelo.


O que vem a seguir?


Nosso gráfico já sabe muito, mas ainda há muito espaço para desenvolvimento. Os planos formam um agrupamento de vários estados, com aninhamento. Isso simplificará bastante as colunas de missões. Os planos também incluem trabalho para melhorar a exibição de gráficos e links. Agora, as conexões em gráficos grandes lembram espaguete (até a cor é semelhante) e, às vezes, é fácil ficar confuso.

Source: https://habr.com/ru/post/pt471956/


All Articles