Você está na página 1de 25

Animações 2D

Mecanim
O sistema de animação da Unity é baseado no conceito de clipes de animação
(Animation Clip), que contém informações sobre como determinados objetos devem
alterar sua posição, rotação ou outras propriedades ao longo do tempo.
Os clipes de animação são então organizados em um sistema estruturado
semelhante a um fluxograma, denominado Animator Controller. O Animator Controller
atua como uma “Máquina de Estado”, que controla qual clipe deve estar sendo
reproduzido no momento e quando as animações devem ser alteradas.

Importando os Assets
Importe para dentro do seu projeto 2D todos os Sprites referentes ao
personagem que será animado. Nesse material utilizaremos como base os Sprites do
personagem Cute Girl baixados do site gameart2d.

Criando o Personagem
Arraste pare dentro da aba Hierarchy o sprite chamado “Idle (1)”, ele servirá
como base para a criação do GameObject do personagem. Renomeie o GameObject
para Personagem.
Em alguns casos os sprites que utilizaremos em nossos projetos podem não estar
como a proporção adequada para o nosso jogo, sejam muito grandes ou muito
pequenos. Para contornar essa situação devemos alterar a sua proporção em relação a
cena apenas modificando a sua propriedade Scale em todos os eixos. No caso do
personagem Cute Girl, ela está um pouco grande, para isso vamos reduzir a sua escala
para 0.4.

Figura 1 - Alterando o Scale


Componentes de uma animação
Na Unity para criarmos animações precisamos obrigatoriamente de três
componentes, independentemente se as animações sejam 2D ou 3D. São eles:

• Animator – usado para atribuir uma animação a um GameObject. O componente


Animator requer uma referência a um Animator Controller;
• Animator Controller – define quais clipes de animação serão usados e controla
quando eles devem ser tocados;
• Animation Clip – é a própria animação do personagem.
Cada personagem ou objeto animado deverá possuir os seus próprios componentes.

Animator Component
Selecione o personagem Cute Girl e adicione o componente Animator. Não
confundir com “Animation”.

Figura 2 – Adicionando o componente Animator

Animator Controller
Agora que o nosso personagem possui um componente Animator, precisamos
criar um Animator Controller e depois associá-lo ao personagem. Dentro do projeto crie
uma pasta chamada Animações, dentro dela crie o Animator Controller clicando com o
botão direito do mouse CREATE >> Animator Controller. Renomeie o Animator
Controller para CuteGirl.

Figura 3 - Animator Controller


Em seguida vamos associar (arrastar) o Animator Controller ao Animator do
Personagem, como demonstra a figura a seguir:

Figura 4 - Associando um Animator Controller a um Animator

Ao clicarmos duas vezes em cima do Animator Controller será exibida uma nova
aba chamada Animator como a mostrada a seguir:

Figura 5 - A aba Animator


A aba Animator tem duas seções principais: a área de layout principal em grade e o
painel Layers (Camadas) e Parameters (Parâmetros) à esquerda.
A seção principal com a grade cinza escura é a área de layout. Você pode usar
esta área para criar, organizar e conectar estados (animações) no seu Animator
Controller. Você pode clicar com o botão direito do mouse na grade para criar novos nós
de estado. Use o botão do meio do mouse ou a tecla Alt para movimentar a câmera.
Clique para selecionar os nós de estado, você pode também reorganizá-los
simplesmente clicando e arrastando os nós.
O painel esquerdo pode ser alternado entre as abas Parameters e Layers. A aba
Parameters permite criar, visualizar e editar os parâmetros que serão utilizados pelo
Animator Controller. Estas são variáveis que você define e que atuam como entradas na
máquina de estados. Para adicionar um parâmetro, clique no ícone “+” e selecione o
tipo de parâmetro no menu pop-up. Para excluir um parâmetro, selecione o parâmetro
nas listas e pressione a tecla delete.
Quando o painel esquerdo é alternado para a visualização Layers, você pode
criar, visualizar e editar camadas no seu Animator Controller. Isso permite que você
tenha várias camadas de animação em um único Animator Controller trabalhando ao
mesmo tempo, cada uma controlada por uma máquina de estado separada.
O Animator Controller gerencia os vários estados de animação e as transições
entre eles usando uma espécie de “Máquina de Estado”, que pode ser considerada
como um tipo de fluxograma, ou um programa simples escrito em uma linguagem de
programação visual dentro da Unity.

Animation Clip
Os clipes de animação (Animation Clip) são um dos principais elementos do
sistema de animação da Unity. A Unity suporta a importação de animação de fontes
externas e oferece a capacidade de criar clipes de animação a partir do zero no editor
usando a janela Animation, que pode ser acessado em WINDOW >> ANIMATION ou
pelo atalho CTRL + 6.
Na maioria das situações, é normal termos várias animações e alternar entre elas
quando certas condições do jogo ocorrem. Por exemplo, você pode alternar de uma
animação de caminhada para um salto sempre que a barra de espaço for pressionada.
No entanto, mesmo se você tiver apenas um único clipe de animação, ainda precisará
colocá-lo em um Animator Controller para usá-lo em um objeto de jogo.
Para criarmos um Animation Clip, clique com o botão direito do mouse dentro
da pasta Animações e selecione CREATE >> ANIMATION. Renomeie o arquivo para
“Parado”.
Figura 6 - Criando uma animação

Esse Animation Clip será o responsável por armazenar a animação que


representa o personagem parado. Porém, antes de animarmos os sprites de parado,
devemos associar esse Animation Clip ao Animation Controller do personagem. Para
fazer essa associação devemos arrastar o Animation Clip “Parado” para dentro do
Animation Controller “CuteGirl” (Antes de arrastar o Animation Clip, verifique se o
Animation Controller desejado está aberto dentro da aba Animator).

Figura 7 - Associando um Animation Clip a um Animation Controller

Com o Animation Clip “Parado” já associado ao seu Animator Controller,


podemos finalmente associar os sprites que serão utilizados para essa animação. Dentro
da pasta Sprites, selecione todos os dezesseis sprites que compõem essa animação (Idle
(1) até Idle (16)) e o arraste para dentro da aba Animation. Altere o número de quadros
da animação de sessenta para vinte e quatro dentro da opção Samples. Para saber um
pouco mais sobre taxa de quadros (FPS) acesse:
https://www.tecmundo.com.br/video/10926-o-que-sao-frames-por-segundo-.htm
Figura 8 - Criando uma animação a partir de sprites

Queremos também que essa animação seja tocada de forma ininterrupta (loop),
ou seja, quando todos os quadros forem tocados a animação deverá ser tocada
novamente a partir do início. Selecione o Animation Clip “Parado” e dentro do painel
Inspector marque a opção Loop Time como mostra a imagem a seguir:

Figura 9 - Animação tocando em loop

Ao entrarmos no modo Play podemos reparar que a animação “Parado” está


sendo executada em loop.
O nosso personagem já é capaz de executar a animação “Parado” de forma
ininterrupta, porém a personagem deve possuir mais três animações de um total de
quatro, são elas: Parado (já criada), Correndo, Pulando e Morrendo.
Vamos agora criar essas três novos Animation Clip repetindo os mesmos passos
utilizados na criação da animação “Parado”, com apenas uma modificação, as animações
“Pulando” e “Morrendo” não precisam ser executadas em loop.
Existem diversas formas para criarmos novos clipes de animação na Unity, uma
delas é acessando a aba Animation com o GameObject que receberá o clip selecionado
dentro da aba Hierarchy. Ao lado esquerdo da opção Samples existe uma caixa com os
nomes de todas as animações já associadas ao GameObject, acessando essa caixa
selecione a opção CREATE NEW CLIP. Renomeie o clipe com o nome desejado e o salve
dentro da pasta de animações. Criando um novo clip com essa abordagem ele já
adicionado automaticamente dentro do Animation Controller do GameObject.

Figura 10 - Adicionando um novo Animation Clip

Transição entre animações


Com todas as quatro animações criadas, vamos acessar a aba Animator. Ela deve
estar com a visualização similar à da figura a seguir (com o clique esquerdo do mouse
você pode reposicionar todos os estados de uma animação):

Figura 11 - Aba Animator após a criação de todas as animações


Acessando a aba Animator, podemos reparar que a animação “Parado” possui
uma cor diferente das demais além de ter uma ligação com a “caixa” chamada Entry.
Mas por que?
Toda que vez que um GameObject animado aparece em uma cena na Unity, a
engine necessita saber qual animação deve ser tocada primeiro. A “caixa” Entry tem
justamente essa finalidade, ou seja, todo clipe ligado a ela será executado antes de todos
os outros. Já o clipe “Parado” possui uma cor diferente (laranja) para explicitar ao
desenvolvedor que esse clipe é o estado padrão (“default state”).
Podemos alterar o clipe padrão clicando com o botão direito do mouse em cima
do estado desejado e selecionar a opção SET AS LAYER DEFAULT STATE.

Figura 12 - Alterando a animação padrão

O nosso personagem deve ser capaz de trocar de um estado (animação) para o


outro, para isso, devemos informar para a Unity que um estado é capaz de transitar para
outro estado, ou seja, a animação “Parado” em algum momento deve parar sua
execução e tocar a animação de “Correndo” e vice-versa.
Vamos agora fazer a transição do estado “Parado” para o estado “Correndo”.
Clique com o botão direito do mouse em cima de “Parado” e selecione a opção Make
Transition e faça a ligação com o estado “Correndo”.

Figura 13 - Fazendo a transição de Parado para Correndo


O estado de “Correndo”, também deve ser capaz de voltar para o estado de “Parado”,
para isso devemos fazer uma nova transição, agora de “Correndo” para “Parado”.

Figura 14 - Fazendo a transição de Correndo para Parado

Ao entrarmos no modo Play, podemos visualizar que existe uma transição entre
as animações. A animação de “Parado” é tocada uma vez até o seu fim e em seguida
ocorre a transição para a animação “Correndo”. Ela também é tocada apenas uma vez e
retorna novamente para a animação “Parado” e esse ciclo é repetido enquanto o jogo
está sendo executado.
Em nosso jogo não queremos que as transições entre as animações ocorram de
forma automática e sim quando determinadas condições forem alcançadas. Por
exemplo, queremos que a animação “Correndo” seja tocada de forma ininterrupta
enquanto o personagem estiver se movendo do contrário a animação “Parado” deve
estar em execução.
Em ambas as setas que representam a transição das animações devemos fazer
algumas modificações. Primeiro, selecione a seta que aponta de “Parado” para
“Correndo” e acesse o painel Inspector.

Figura 15 - Editando a transição entre animações


• Desmarque a opção Has Exit Time;
• Desmarque a opção Fixed Duration;
• Altere o valor da opção Transition Duration para ZERO.

Figura 16 - Removendo a transição automática e o "delay" na troca de animações

Repita os mesmos passos na transição entre as animações de “Correndo” para “Parado”.

Movimentando o jogador
Com as animações de “Parado” e “Correndo” já criadas e configuradas, vamos
adicionar o movimento ao nosso personagem. Primeiro devemos adicionar alguns
outros componentes como o Box Collider 2D e o Rigidbody 2D.
Após adicionar o Box Collider 2D ao personagem ajuste o colisor (clicando em
Edit Collider) para que fique mais ou menos com a mesma dimensão do sprite do
personagem. Tente alinhar a parte de baixo do colisor com os pés do personagem para
evitar dar a impressão que o personagem está flutuando na cena.

Figura 17 - Editando o Box Collider 2D


Precisamos fazer também um pequeno ajuste dentro do Rigidbody 2D, acesse a
sub propriedade Contraints e marque a opção Freeze Rotation no eixo Z, isso evitará
que ao movimentarmos o personagem pelo cenário ele rotacione pela cena ao colidir
com algum desnível ou rampa.

Figura 18 - "Travando" a rotação no eixo Z

Para evitar que o personagem cai no “infinito” por causa da ação da física da
Unity, vamos adicionar uma plataforma a cena. Dentro da pasta Sprites clique com o
botão direito e acesse CREATE >> SPRITES >> SQUARE. Renomeie o arquivo para bloco.

Figura 19 - Criando um sprite

Em seguida posicione o sprite bloco na parte de baixo da cena e chame esse


GameObject de Plataforma, redimensione-o para que sua largura seja um pouco maior
que a largura da tela (câmera). Adicione também um componente do tipo Box Collider
2D, isso fara com que a nossa personagem consiga se movimentar em cima da
plataforma.

Figura 20 - Adicionando uma plataforma

Em seguida crie um novo Script chamado ControlaPersonagem e o associe ao


GameObject Personagem.

Figura 21 - Composição final do GameObject Personagem

O script ControlaPersonagem contém toda a lógica que permitirá ao nosso


personagem se mover e animar. Na verdade, é um componente que está ligado ao
personagem. Esse script implementa três funções (Movimentar, Pular e Virar), uma para
cada ação, além disso, esse componente deve levar em consideração o componente
Animator, para mostrar a animação certa para o personagem.
Vamos começar adicionando três variáveis: uma que irá armazenar o
componente Animator (anim), outra para o Rigidbody2D (rb) e por fim uma outra que
controlará a velocidade de deslocamento do personagem (velocidade).
Podemos acessar os componentes Animator e Rigidbody2D do personagem
dentro do método Awake chamando o método GetComponent ().
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ControlaPersonagem : MonoBehaviour {


[SerializeField] private float velocidade = 5;
private Rigidbody2D rb;
private Animator anim;

private void Awake()


{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}

private void FixedUpdate()


{
float movimentoHorizontal = Input.GetAxis("Horizontal");

Movimentar(movimentoHorizontal);
}

private void Movimentar(float movimento)


{
rb.velocity = new Vector2(movimento * velocidade, rb.velocity.y);
}
}
O primeiro método que vamos criar será o Movimentar, que tem como
parâmetro um valor do tipo float chamado movimento que será responsável por indicar
a direção do movimento. Dentro desse método iremos atribuir a propriedade velocity
(que pertence à classe Rigidbody2D) um objeto do tipo Vector2 que contém em seu
primeiro parâmetro a movimentação no eixo X (movimento * velocidade), enquanto no
segundo parâmetro (eixo Y) iremos atribuir o próprio valor da velocidade em seu próprio
eixo, não alterando o seu valor.
Ao executarmos o jogo, podemos ver que o personagem possui uma
movimentação bem suavizada e controlada pelas setas do teclado ou pelas teclas A e D.

Alterando o estado de parado para correndo


Agora que o personagem já está se movendo pela cena, devemos efetuar a troca
de animações. Para trocarmos de animação de forma dinâmica na Unity devemos
primeiro definir como a transição deve ser efetuada. Dentro da Unity vamos acessar o a
janela Animator e depois o painel Parameters.
Precisamos criar um parâmetro que será o responsável pela troca da animação
“Parado” para a animação “Correndo”. A transição entre essas animações deverá ter
como base a velocidade do personagem no eixo X, ou seja, quando a velocidade do
personagem for maior que ZERO, o personagem estará se movimentando e com isso a
animação “Correndo” deverá ser executada. Quando a velocidade em X for menor que
ZERO, o personagem estará parado e assim a animação “Parado” deverá ser executada
novamente.
Figura 22 - Parâmetros de uma animação

Clique no botão “+” e selecione a opção float. Renomeie esse parâmetro para
velocidade.

Figura 23 - O parâmetro velocidade

Com o parâmetro velocidade criado, devemos associá-lo a transição de “Parado”


para “Correndo”. Clique na seta que representa essa transição e dentro do painel
Inspector, acesse Conditions e clique no botão “+”.

Figura 24 - Adicionando uma condição a uma transição


Na caixa de seleção que irá aparecer dentro da seção Conditions, selecione o
parâmetro criado anteriormente (velocidade), em seguida o valor Greater e por ultimo
defina o valor como 0.01.

Figura 25 - Parâmetro da transição entre Parado para Correndo

A seguir faremos praticamente o mesmo com a transição de “Correndo” para


“Parado”, onde iremos apenas alterar o valor de Greater para Less.

Figura 26 - Parâmetro da transição entre Correndo para Parado

Com o parâmetro de transição entre as animações definido, podemos retornar a


classe ControlaPersonagem. Vamos colocar dentro do método Update a
responsabilidade de executar a troca de animações frame após frame. Em particular,
precisamos definir o parâmetro velocidade criado dentro da máquina de estados da
animação com a velocidade do personagem ao longo do eixo x.
Vamos fazer uma chamada a função SetFloat que pertence à classe Animator
utilizando a variável anim. Este método faz referência a todos os parâmetros criados
dentro do Animator que sejam do tipo float. Devemos passar como o primeiro
parâmetro do método uma string que representará o parâmetro criado anteriormente
(o valor passado como string deve ser escrito de forma igual ao parâmetro criado dentro
do painel Animator, respeitando caracteres maiúsculos e minúsculos).
O segundo parâmetro é o valor que atribuiremos ao parâmetro velocidade.
Utilizaremos o método Abs da classe Mathf para podermos extrair o valor absoluto (sem
sinal) da propriedade velocity.
/*Continua a classe ControlaPersonagem acima*/

private void Update()


{
anim.SetFloat("velocidade", Mathf.Abs(rb.velocity.x));
}

/*Continua a classe ControlaPersonagem abaixo*/


Ao entrarmos no modo Play podemos ver a troca de animações ocorrendo
sempre que há alguma alteração na velocidade do personagem.

“Virando” o Personagem (Flip)


Ao movimentarmos o nosso personagem utilizando as setas do teclado ocorre a
transição entre as animações perfeitamente, porém quando andamos para trás
utilizando a seta para a esquerda podemos notar que o personagem faz um verdadeiro
“Moonwalk” (Michael Jackson).
Para corrigirmos esse bug precisamos adicionar uma variável booleana a nossa
classe ControlaPersonagem, ela será responsável por controlar a direção para onde o
personagem deve estar virado no momento. Vamos chamar essa variável de
viradoParaDireita e iniciar o seu valor com true dentro do método Start.
Sempre que o personagem estiver virado para a direita o valor da variável deverá
ser true, caso ele esteja virado para a esquerda o valor deverá ser alterado para false.
public class ControlaPersonagem : MonoBehaviour {
[SerializeField] private float velocidade = 5;

private bool viradoParaDireita;

private Rigidbody2D rb;


private Animator anim;

private void Awake()


{
rb = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}

private void Start()


{
viradoParaDireita = true;
}
/*Continua a classe ControlaPersonagem abaixo*/

O controle da variável viradoParaDireita deverá ser efetuado pelo método


Virar(), que será criado dentro da classe ControlaPersonagem. Este método receberá
com parâmetro um valor do tipo float chamado de movimento que será responsável por
indicar a direção na qual o personagem está se movendo. O método Virar funcionará da
seguinte forma:
• caso o personagem esteja virado para a esquerda (viradoParaDireita == false) e
o movimento do personagem é alterado para a direita (movimento > 0) ou;
• caso o personagem esteja virado para a direita (viradoParaDireita == true) e o
movimento do personagem é alterado para a esquerda (movimento < 0);
Caso alguma das condições acima seja verdadeira, deverá ser efetuado o
espelhamento dos sprites do personagem. Para espelharmos um GameObject, podemos
multiplicar a propriedade localScale somente no eixo X por -1, fazendo com que o sprite
vire sempre para o lado oposto ao atual. Não devemos esquecer que logo após fazer o
“flip” do personagem devemos também inverter o valor da variável viradoParaDireita.
/*Continua a classe ControlaPersonagem acima*/
private void Movimentar(float movimento)
{
rb.velocity = new Vector2(movimento * velocidade, rb.velocity.y);
Virar(movimento);
}

private void Virar(float movimento)


{
if((viradoParaDireita == false && movimento > 0) || (viradoParaDireita ==
true && movimento < 0 )) {
transform.localScale = new Vector3( transform.localScale.x * -1,
transform.localScale.y,
transform.localScale.z);
viradoParaDireita = !viradoParaDireita;
}
}

/*Continua a classe ControlaPersonagem abaixo*/

Para finalizar devemos chamar o método Virar dentro do método Movimentar


passando o valor da variável movimento como parâmetro. Ao executarmos o jogo
podemos ver o espelhamento do sprite funcionando perfeitamente.

O sistema de pulo
Para criarmos um mecanismo de pulo eficiente dentro do jogo é necessário
adicionarmos novos elementos ao projeto. Primeiro, precisamos criar algo que sirva
como referência para a posição dos “pés” do personagem. Esse mecanismo deverá ser
capaz de nos informar quando o personagem estiver em contato com o chão ou em algo
no qual ele possa se locomover normalmente.
Segundo, precisamos criar uma forma de diferenciar os tipos de terreno
existentes no jogo e que também que seja capaz de enviar a informação de que ouve
uma colisão com o jogador ou qualquer outro objeto do jogo.
Uma vez que definirmos esses dois novos componentes, podemos entrar em
ação com o sistema de pulo. O sistema de pulo deverá entrar em ação apenas quando o
jogador apertar o botão designado para pular e se o personagem estiver em contato
com alguma superfície que lhe proporcione o pulo (evitando pulos no ar ou em
superfícies grudentas por exemplo).
Vamos definir a posição dos “pés”. Crie um GameObject vazio dentro do
personagem e o posicione entre as suas pernas próximo ao seus pés. Renomeie esse
GameObject para “Posicao dos pes”. Para facilitar a visualização da posição dos pés,
vamos adicionar um ícone colorido a ele.

Figura 27 - Adicionando um ícone a um GameObject

Em seguida vamos criar uma Layer (camada) que será usada para diferenciar qual
o tipo de terreno onde os “pés” do personagem estarão colidindo. Layers (camadas) são
comumente usadas pelas câmeras para renderizar apenas uma parte da cena e pelas
luzes para iluminar apenas algumas partes do cenário. Também podem ser utilizados
por raycasting e para ignorar seletivamente Colliders e ou para criar colisões.
Para criarmos uma nova Layer, acesse o menu Inspector, clique dentro da caixa
de seleção Layer e na opção Add Layer.

Figura 28 - Adicionando uma Layer

Após acessar a janela Tags & Layers, na linha oito, crie a layer chamada “chao”.

Figura 29 - Criando uma layer


Em seguida selecione o GameObject Plataforma e associe a layer chao a ele. Todo
GameObject em nosso jogo que possuir o comportamento de chão deverá possuir a
layer “chao”.

Figura 30 - Atribuindo a layer chao

Com todas as modificações necessárias para o sistema de pulo prontas, podemos


voltar para o script ControlaPersonagem e fazer algumas adições. Primeiro,
precisaremos criar mais cinco variáveis:

• alturaDoPulo: irá definir a força do pulo do personagem;


• estaNoChao: irá verificar quando o personagem está com os pés no chão;
• posicaoDosPes: irá armazenar a posição do GameObject posicaoDosPes;
• raioPosicaoDosPes: define o tamanho do raio da circunferência que irá verificar
a colisão com a camada chão;
• mascaraChao: irá armazenar a layer considerada chão;
public class ControlaPersonagem : MonoBehaviour {
[SerializeField] private float velocidade = 5;
[SerializeField] private float alturaDoPulo = 5;

private bool viradoParaDireita;


private bool estaNochao;

[SerializeField] private Transform posicaoDosPes;


[SerializeField] private float raioPosicaoDosPes = 0.2f;
[SerializeField] private LayerMask mascaraChao;

private Rigidbody2D rb;


private Animator anim;

/*Continua a classe ControlaPersonagem abaixo*/

Dentro do método FixedUpdate, iremos utilizar o método OverlapCircle da classe


Physiscs2D. Esse método irá criar um círculo imaginário baseado nos parâmetros
passados e retornará true caso esse circulo tenha contato com a layer designada. Vamos
atribuir o valor de retorno deste método a variável estaNoChao;
/*Continua a classe ControlaPersonagem acima*/

private void FixedUpdate()


{
estaNochao = Physics2D.OverlapCircle( posicaoDosPes.transform.position,
raioPosicaoDosPes, mascaraChao);
float movimentoHorizontal = Input.GetAxis("Horizontal");

Movimentar(movimentoHorizontal);
}
/*Continua a classe ControlaPersonagem abaixo*/

Apesar da função acima funcionar de forma satisfatória, não conseguimos


visualizar a circunferência de colisão dos pés do personagem com o chão. Felizmente a
classe MonoBehaviour possui um método chamado OnDrawGizmos que tem a
capacidade de desenhar formas que podemos utilizar para testar (debugar) certas
funções dentro do jogo. O desenho realizado pelo método OnDrawGizmos será somente
exibido dentro da aba Scene do jogo.
/*Continua a classe ControlaPersonagem acima*/

private void OnDrawGizmos()


{
Gizmos.color = Color.red; //Altera a cor da linha do desenho, por padrão a
cor será branca;
Gizmos.DrawWireSphere(posicaoDosPes.position, raioPosicaoDosPes);
}

/*Continua a classe ControlaPersonagem abaixo*/

Figura 31 - Desenhando a circunferência de colisão

Com o mecanismo que atribui valor a variável estaNoChao funcionando, vamos


criar o método Pular dentro da classe ControlaPersonagem.
O pulo do personagem deverá ser efetuado sempre que a tecla espaço for
pressionada (a tecla espaço é mapeada por padrão como “Jump” dentro do painel Input
na Unity) e se o valor da variável estaNoChao for true. Caso as duas condições sejam
verdadeiras, adicionaremos um força (AddForce) utilizando como base o vetor que
aponta para cima (Vector2.up) multiplicados pela força do pulo (alturaDoPulo). Para
suavizarmos o movimento do pulo iremos passar como segundo parâmetro a
propriedade Impulse da classe ForceMode2D.
/*Continua a classe ControlaPersonagem acima*/
private void Pular()
{
if(Input.GetButtonDown("Jump") && estaNochao == true)
{
rb.AddForce(Vector2.up * alturaDoPulo, ForceMode2D.Impulse);
}
}
/*Continua a classe ControlaPersonagem abaixo*/
A chamada do método Pular deverá ser feita dentro do método Update.
/*Continua a classe ControlaPersonagem acima*/
private void Update()
{
anim.SetFloat("velocidade", Mathf.Abs(rb.velocity.x));
Pular();
}

/*Continua a classe ControlaPersonagem abaixo*/


Ao executarmos o jogo e pressionarmos a tecla espaço podemos ver o
personagem executando o pulo de forma satisfatória.

Figura 32 - Executando o pulo

Executando a animação de pulo


Para deixar o nosso pulo mais realista devemos fazer com que a animação de
pulo seja tocada toda vez que o jogador não estiver com o GameObject “posicao dos
pes” em contato com a camada chão. Iremos utilizar como base a propriedade
estaNoChao da classe ControlaPersonagem.
Dentro da Unity acesse a janela Animator e vamos criar um novo parâmetro do
tipo Bool. Nomeie esse parâmetro de estaNoChao.
Figura 33 - Criando um parâmetro booleano para controlar a transição da animação “Pulando”

Em seguida iremos fazer as transições entre as animações:

• Parado → Pulando
• Pulando → Parado
• Correndo → Pulando

Figura 34 - Transições para a animação "Pulando"

Não se esqueça de remover a transição automática entre as animações e o


“delay” na troca entre elas. Selecione a seta que indica a transição e faça os seguintes
ajustes em todas as transições para a animação “Pulando”.

• Desmarque a opção Has Exit Time;


• Desmarque a opção Fixed Duration;
• Altere o valor da opção Transition Duration para ZERO.
A troca do estado de “Parado” para “Pulando” deverá ser efetuada sempre que
o valor do parâmetro estaNoChao for false, ou seja, quando os pés do personagem não
estiverem em contato com o chão.
Quando o valor de estaNoChao for true ocorrerá a troca de estado no sentido
contrário. O mesmo raciocínio será aplicado na troca de estados de Correndo para
Pulando.
Figura 36 – Condição de troca de Parado para Pulando Figura 35 - Condição de troca de Pulando para Parado

Figura 37 - Condição de troca de Correndo para Pulando

Com a transição entre as animações e os parâmetros definidos corretamente,


vamos adicionar dentro do método Update da classe ControlaPersonagem uma
chamada ao método SetBool da classe Animator que será o responsável por executar o
gerenciamento da animação de “Pulando”.
/*Continua a classe ControlaPersonagem acima*/
private void Update()
{
anim.SetFloat("velocidade", Mathf.Abs(rb.velocity.x));
anim.SetBool("estaNoChao", estaNochao);
Pular();
}

/*Continua a classe ControlaPersonagem abaixo*/


Ao entrarmos no modo Play, podemos ver a animação de pulo funcionando
corretamente.

Eliminando o bug da parede (Physics Materials 2D)


O nosso jogo possui um pequeno bug quando o personagem encosta em alguma
parede ou objeto. Para podermos visualizar essa situação duplique a plataforma e a
redimensione como a imagem a seguir:

Figura 38 - Duplicando a plataforma


Entre no modo Play e execute um pulo perto do grau formado entre as
plataformas e continue segurando as setas de movimento no teclado. Podemos reparar
que enquanto as setas estão pressionadas o personagem fica preso como se estive
“travado”.

Figura 39 - personagem travado na plataforma

Podemos corrigir esse efeito indesejado aplicando um material especial a


superfície da plataforma. Na Unity podemos alterar o comportamento de uma superfície
utilizando um objeto do tipo Physics Material 2D. Para criarmos um objeto desse tipo
clique com o botão direito dentro do painel Project em seguida selecione CREATE >>
PHYSICS MATERIAL 2D.

Figura 40 - Criando um objeto do tipo Physics Material 2D

Nomeie esse material para “escorregadio” e o coloque dentro de uma pasta


chamada “superfícies”.

Figura 41 - O material escorregadio


Quando se trata de um Physics Material 2D na Unity, existem apenas dois
parâmetros a serem levados em consideração:

• Friction: indica a quantidade de atrito; quanto menos atrito, mais escorregadio


é o material.
• Bounciness: Indica quanta energia o material devolve quando algo atinge o
material.
Para tornar o nosso material escorregadio e assim evitar que o nosso
personagem fique grudado nas paredes altere o valor da propriedade Friction para
ZERO.

Figura 42 - Tornando o material escorregadio

Para aplicarmos um material desse tipo a uma superfície ou a um GameObject


devemos associá-lo diretamente a propriedade Material do seu componente Collider
(no caso da plataforma um Box Collider).

Figura 43 - Associando o material escorregadio a plataforma

Não esqueça de aplicar o material a todos os GameObjects do seu jogo que


necessitem desse efeito.

Você também pode gostar