Aprendendo a programar jogos em Unity: animações 2D dos objetos coletáveis de uma fase

Vamos criar uma animação para os itens coletáveis e conhecer estados, transições e fluxos de um Animation Controller.

em 27/01/2024
Seja bem-vindo(a) ao GameDev: Aprendendo a programar jogos em Unity de hoje! Dando prosseguimento ao desenvolvimento de nosso platformer 2D, criaremos uma nova animação com parâmetros diferentes da anterior e aprenderemos mais sobre estados e transições, dentro da estrutura das ferramentas de animação que a plataforma nos oferece.


Caso esta seja a primeira vez que você acessa nossa série, junte-se a nós nesta caminhada de aprendizado para, juntos, aprendermos mais sobre tópicos importantes relativos ao desenvolvimento de jogos. A partir do primeiro tópico, você poderá conhecer mais sobre como é desenvolvido um game utilizando a plataforma Unity e terá a oportunidade de desenvolver, pondo a “mão na massa”, divertidos e desafiadores projetos, de diferentes gêneros e estilos.

Nossa série é elaborada de forma a permitir, por meio de exemplos e projetos, que você possa criar “do zero” os games que sempre sonhou em tirar do papel. No momento, estamos elaborando Motorista da Pesada, um platformer 2D em que o jogador deve coletar, no menor tempo possível, caixas de presente que foram espalhadas pelos cenários. Para isso, ele deve guiar um simpático carrinho por diferentes caminhos entre as fases, tomando cuidado para não tocar em perigosas bombas, que podem representar o fim de sua jornada.


No tópico anterior de nossa jornada começamos a entender como funcionam as ferramentas para aplicação de animações aos GameObjects do Unity. Criamos uma breve animação baseada em troca de sprites e realizamos sua aplicação nos objetos que representam as bombinhas, agora bem “animadas” e espalhadas pela primeira fase de nosso game. Venha conosco e vamos juntos nesta jornada rumo a novos conhecimentos!

Técnicas de animação

As ferramentas de animação do Unity permitem a modificação de diversos parâmetros de nossos GameObjects. Em nosso último encontro, ao animarmos os objetos que representam as bombas de nossa fase, configuramos via janela Animation a alteração dos sprites ritmicamente, três vezes por ciclo, utilizando todos os desenhos de bombinhas que tínhamos à disposição em nosso conjunto de Assets. Para recordarmos, o resultado foi este:

Porém, não é apenas por meio de alterações de sprites que podem ser realizadas animações em objetos bidimensionais: outros elementos podem receber modificações em seus parâmetros, como o posicionamento e a rotação de um Transform, por exemplo.

A utilização de uma técnica (ou mesmo de diversas, simultaneamente) permite ao desenvolvedor dar vida aos seus elementos da forma que ele considerar mais adequada. Em jogos como Pokémon Platinum (DS), a combinação de técnicas envolvendo troca de sprites, movimentação e escalonamento de imagens pôde produzir animações interessantes e vibrantes, como as demonstradas a seguir:


Para que possamos experimentar também em nosso jogo um pouco do que o Unity oferece em termos de animações 2D, criaremos uma nova para nossos objetos coletáveis (os presentes) em que iremos alterar parâmetros relativos aos seus componentes do tipo Transform.

Animando os presentes

Vamos começar, então, criando as animações, antes de atribuí-las aos objetos coletáveis. Abra o Unity Hub e clique duas vezes sobre o item referente ao projeto Motorista da Pesada. Na interface inicial do Unity, na aba Project, abra a pasta Assets, Scenes e, por fim, clique duas vezes no ícone da cena Fase01.
Na tela inicial do editor, clique no menu Window, submenu Animation e, por fim, na opção Animation:

A janela Animation será apresentada, sobreposta à janela principal do editor. Selecione, na aba Hierarchy, o GameObject Coletavel01. Veja que, agora, é exibida na área central da janela Animation uma opção para criarmos uma animação para Coletavel01. Clique, então, no botão Create, em destaque na imagem a seguir:

Na janela Create New Animation, salve o arquivo dentro da pasta Animacoes com o nome “AnimacaoPresente”, sem as aspas, conforme exemplo:

Após a criação do arquivo, novas opções serão apresentadas à janela Animation, somente enquanto Coletavel01 estiver selecionado na aba Hierarchy.

Vamos iniciar a criação da animação propriamente dita, na janela Animation, clicando no botão Add Property. Selecione a opção Transform, Rotation e clique no sinal de mais (+) conforme exemplificado a seguir:

O parâmetro que iremos alterar em nossa animação é a rotação: iremos “chacoalhar” levemente nossas caixinhas por meio de duas alterações pontuais a serem realizadas no parâmetro Rotation de seus respectivos Transforms.

Clique na seta (destacada em vermelho, na imagem a seguir) para exibir os três eixos de rotação do objeto (Rotation.x, Rotation.y e Rotation.z):

Iremos indicar ao Unity que sejam concedidos dois valores específicos de rotação no eixo Z do objeto em dois momentos: no 20º frame da animação e no 40º frame. Se a animação durar um segundo, seguindo o padrão de 60 frames por segundo, os momentos seriam aproximadamente em 0,33 e 0,66 segundo, respectivamente.

Para isso, vamos clicar no botão Preview e, em seguida, digitar “20”, sem as aspas, na caixa de texto em destaque da imagem a seguir. Isso fará com que a linha do tempo se posicione no momento respectivo ao 20º frame da animação:

No campo Rotation.z iremos inserir o valor -20. Veja que, agora, assim como aconteceu com a animação que criamos para as bombinhas, um pequeno losango apareceu na posição determinada, indicando que, naquele momento, será realizada uma alteração de valor de um dos parâmetros; no caso, uma modificação na rotação do objeto em seu eixo Z:

Agora, na caixa de texto em destaque da imagem a seguir, digite “40”, sem as aspas, para irmos ao momento correspondente ao 40º frame da animação. Note que, mesmo sem inserirmos nenhuma informação específica de rotação, o valor de Rotation.z no referido momento está diferente (-10):

Isso ocorre pois, por padrão, as animações com modificação de parâmetros de Transform geradas no Unity apresentam suavidade; ou seja, nosso objeto não irá bruscamente alterar sua rotação, mas sim transitar entre os valores informados por nós e os valores-padrão do primeiro e do último frame, que normalmente são zero (0), mas que podem ser alterados.

Agora, iremos inserir o valor 20 em Rotation.z para esse momento, no lugar de -10, que havia sido calculado automaticamente pelo Unity. Novamente, um pequeno losango aparecerá na posição determinada.

Experimente apertar o botão Play da janela Animation e veja como os valores de Rotation.z são alterados dinamicamente durante a execução da animação. Ao final, pressione novamente para interromper a simulação. 

Agora, iremos fechar a janela Animation e experimentar a execução do game em si, indo à aba Game e pressionando o botão Play. Aproxime seu carrinho de Coletavel01 e veja a animação que acabamos de criar.

Interrompa a simulação da execução, pressionando novamente o botão Play e retornando à aba Scene.

Fluxos de animação

Uma das características interessantes do sistema de animações presente no Unity é a possibilidade de se realizar alterações dinâmicas em parâmetros da animação, ou mesmo a troca da animação utilizada no momento, por meio dos Animation Controllers.

Vamos abrir o Animation Controller de Coletavel01 selecionando-o e, na aba Inspector, clicando duas vezes sobre o item do parâmetro Controller de seu componente Animator.

A aba Animator será apresentada no centro da janela do editor. Relembrando o que vimos em nosso último encontro, os retângulos coloridos da imagem a seguir representam estados de animação em que o objeto pode se encontrar em determinado momento.

Por meio das ferramentas presentes dentro da aba Animator, podemos criar, para um controlador de animação de um objeto, um fluxo que permitirá ao objeto transitar entre diferentes estados de animação e, assim, se comportar de uma maneira mais “dinâmica”. Esse fluxo é representado pelo conjunto de setas e retângulos apresentados na janela.

Vamos utilizar algumas dessas ferramentas para dar um “agito extra” ao comportamento das caixas de presente, sem precisar modificar a animação em si que criamos agora há pouco.

Criaremos um fluxo que fará o GameObject se comportar da seguinte forma:
  • Será executada a animação que criamos, pelo período de um segundo;
  • A caixa de presente não se movimentará por um instante;
  • Será executada a animação que criamos de forma espelhada, por um segundo; e
  • Novamente, não haverá movimento da caixa de presente por um instante.
O ciclo de animação será repetido até que o jogo acabe ou a caixa de presente seja coletada.

Criando estados

Vamos começar a desenhar o fluxo, criando um novo estado que representará o “instante parado”. Em uma área vazia da tela da aba Animator, clique com o botão direito e, no menu suspenso, selecione o submenu Create State e, por fim, Empty.

Um novo retângulo, desta vez na cor cinza, aparecerá na tela. Trata-se de nosso novo estado de animação. Clique nele e, na aba Inspector, dê-lhe o nome de “Espera”, sem as aspas. Observe que ele não tem uma animação indicada em seu campo Motion, diferente do verificado para o estado AnimacaoPresente.

Agora, clique com o botão direito sobre o retângulo representando o estado AnimacaoPresente e clique em Copy.

Em uma área vazia da tela da aba Animator, clique com o botão direito e, no menu suspenso, selecione a opção Paste.

Uma cópia do estado AnimacaoPresente será criada, desta vez na cor cinza, sob o nome “AnimacaoPresente 0”, sem as aspas. Na aba Inspector, altere o parâmetro Mirror, clicando sobre sua caixa de seleção. É esse atributo que fará com que, em determinado momento do fluxo de estados, a animação seja executada de forma espelhada.

Clique com o botão direito sobre o retângulo representando o estado Espera e clique em Copy. Em uma área vazia da aba Animator, clique com o botão direito e, no menu suspenso, selecione a opção Paste. Será criado um novo estado, de nome “Espera 0”, sem as aspas.

Já temos os quatro estados de nosso ciclo de animação na tela. Se desejar, pode clicar e arrastar os retângulos para melhor organizá-los na área disponível.

Transições entre estados

Embora os estados já tenham sido inseridos no Animation Controller, precisamos agora indicar ao Unity quais serão as transições entre eles e a ordem correta de execução, e é isso o que faremos agora.

Clique com o botão direito sobre o retângulo representando o estado AnimacaoPresente e selecione a opção Make Transition.

Note que aparecerá uma flecha “grudada” à seta de seu mouse. Clique sobre o estado Espera e veja que, agora, foi criado um caminho entre os dois estados. Esse caminho (a seta branca) indica a qual estado será realizada a transição a partir de AnimacaoPresente, ou seja, qual é a próxima animação a ser executada ou, nesse caso específico, a “não-animação”, pois Espera é um estado que fará nosso objeto ficar parado por um instante.

Realize as mesmas ações para criar transições entre os seguintes estados:
  • Origem: “Espera”. Destino: “AnimacaoPresente 0”;
  • Origem: “AnimacaoPresente 0”. Destino: “Espera 0”; e
  • Origem: “Espera 0”. Destino: “AnimacaoPresente”.
Podemos observar que criamos algo bem interessante: um ciclo de animação, conforme a imagem a seguir bem exemplifica:

Finalizando esse processo, clique com o botão direito sobre o nome da aba Animator e selecione a opção Close Tab.

Vamos ver como ficou nossa nova animação? Vá até a aba Game, pressione Play e desloque o personagem principal até chegar próximo ao objeto Coletavel01. Veja como a animação da caixinha está bem mais interessante e polida:

Não se esqueça de interromper a execução, clicando novamente no botão Play. Salve a cena (menu File, Save) e o projeto (menu File, Save Project) antes de fechar o Unity.

Próximos passos

Conseguimos, por meio da elaboração da animação das caixas de presente, aprender um pouco mais sobre o sistema de animações do Unity, sobre outras abordagens de animação 2D que vão além da troca de sprites e, também, em relação aos estados, transições e fluxos presentes na estrutura dos Animation Controllers.

Em nosso próximo encontro, iremos finalizar a construção da primeira fase e dar início à elaboração das próximas. Estamos quase lá! Continue conosco e vamos em frente, rumo ao final desse épico projeto.

Nosso próximo texto já encontra-se disponível, continue conosco nessa jornada de conhecimento e fique ligado sempre aqui no GameBlast!

Revisão: Ives Boitano

Entendo videogames como sendo uma expressão de arte e lazer e, também, como uma impactante ferramenta de educação. No momento, doutorando em Sistemas da Informação pela EACH-USP, desenvolvendo jogos e sistemas desde 2020. Se quiser bater um papo comigo, nas redes sociais procure por @RodrigoGPontes.
Este texto não representa a opinião do GameBlast. Somos uma comunidade de gamers aberta às visões e experiências de cada autor. Escrevemos sob a licença Creative Commons BY-SA 3.0 - você pode usar e compartilhar este conteúdo desde que credite o autor e veículo original.