O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

Como controlar animações & Mixamo.com

Iniciado por MayLeone, 09/04/2018 às 17:36

Introdução:
Olá pessoal, como vão? Hoje estou aqui para ensinar como controlar animações utilizando o componente de controle de animação da Unity (Animation Controller) e para falar um pouco sobre o site Mixamo.com.





Primeiramente, gostaria de convidá-los a conhecer o já citado mixacom.com, um website voltado à tecnologia 3D que visa facilitar a vida dos desenvolvedores de games, disponibilizando um acervo fantástico de animações pré-prontas que possuem uma movimentação bem fluída e com configuração de parâmetros (como espaçamento entre braços, intensidade de movimentos e etc) na própria interface, tudo isso de graça bastando um rápido cadastro no site e estar com o Adobe Flash atualizado!

Na aba "Characters" você encontra alguns personagens já disponíveis pelo site para que você possa utilizar em seu projeto, basta escolher um:



Você também pode fazer o upload do seu próprio modelo (ou de outro site), bastando clicar no botão "UPLOAD".
O mixamo.com disponibiliza um sistema de auto rigger de qualidade, seu único trabalho é demarcar os anéis nos locais certos para que o algoritmo faça a detecção de cada parte do corpo do seu personagem: 



Na aba "Animations" você vai encontrar as mais variadas animações para seu jogo:



Para selecionar uma animação e visualizá-la no personagem desejado, bastar clicar sobre a mesma e vê-la fluir (no canto direito da tela):

Clique aqui para ver!

Veja que na tela da animação você pode gerenciar a visão da câmera, bem como a rotação, aproximação, movimentação e etc:


E também ajustar parâmetros de animação, como intensidade, velocidade de execução, espaçamento entre pontos, postura do personagem e etc:


*Marque a opção "In place" se não quiser que o personagem de fato se movimente pelo jogo, apenas reproduza a animação.

É possível filtrar a pesquisa por animações através da barra de buscas localizada no canto superior esquerdo da tela. Você pode buscar por uma animação específica bastando digitar a palavra-chave (ex: "Walking") ou pode filtrar a pesquisa através das tags do site:


Para nosso tutorial, vamos fazer com que o personagem tenha a animação andando, parado e dando um combo de ataques (chutes e socos), então para seguir o tutorial, pesquise por animações que correspondem a estes requisitos e baixe-as.
Para baixar, clique sobre o botão "Download" e essa tela aparecerá:



Mude a opção "Format"para ".FBX for Unity" e baixe a primeira animação com a opção "Skin" em "With Skin" e as demais com a opção "Without Skin", pois com a Skin iremos baixar o modelo 3D do personagem e com a opção "Without skin" iremos baixar apenas as animações (movimentos e parâmetros).





Trabalhando com a Unity:
Uma vez com a engine Unity aberta, crie uma pasta no seu jogo chamada "Characters" e arraste todas as animações baixadas para dentro desta pasta:



Agora coloque na cena a animação que possui Skin.
Veja no inspector que este objeto já possui um componente incluso, justamente o Animator Controller, porém não existe um controlador atachado a este componente, por enquanto:


Para acabar com este problema, vá até a pasta "Characters" e com o lado direito do mouse vá em "Create" >> "Animator Controller", e coloque o nome que desejar, dessa forma você estará criando um controlador para o componente do seu personagem. Ao clicar duas vezes neste objeto, você abrirá esta janela:



Através desta janela você poderá controlar o fluxo de animações do personagem que possui este componente como controller.
Arraste a animação do personagem parado para esta janela e veja o que ocorre:



Agora você possui uma transição de entrada de cena para a animação do zombie parado!
Essa setinha laranja que conecta os dois estados se chama "transition" (transição) e será através dela que iremos controlar quais animações deverão ser executadas e em quais momentos isso deve ocorrer.
Porém, primeiramente vamos testar o que ocorre quando você referencia este controller criado no "Animator Controller" do personagem através do inspector:



Aperte play e perceba que a animação até é executada, mas quando chega ao final ela para. Concorda que para esse tipo de animação, o ideal seria a animação continuar num loop infinito? Pois bem, para colocar uma animação em loop, basta clicar sobre ela na janela de "Assets" e através do inspector na janela "Animations", marque a opção "Loop time":



Aplique a alteração e perceba que agora a animação realmente entra num loop, terminando e recomeçando.
Se você colocar o layout da interface em 2 por 3 e der play no jogo com a janela do Animator aberta e com o personagem selecionado, você vai poder visualizar a animação sendo executada em runtime:

Clique aqui para ver!

Para criar o restante do fluxo, arraste as outras animações para a janela do Animator Controller:



Agora é hora de criar as transições!
Na animação "Idle" clique com o lado direito do mouse e vá à opção "Make Transition" e conecte a setinha com a animação "Walk", também faça o inverso e crie uma transição de "Walk" para "Idle":



Dessa forma você terá transições da animação "parado" para "andando" e de "andando" para "parado":



Dê play no jogo e veja que após a animação do personagem parado acabar, se inicia a animação dele andando, porém, no jogo não é isso que queremos! Apenas deve-se realizar a animação do personagem andando quando ele de fato andar, não assim em sequência como está.
Para gerenciar as transições de forma correta nós iremos utilizar um artifício da Unity e do Animator Controller que são os parâmetros:



Existem 4 tipos de parâmetros: Bool, Trigger e os numéricos (int e float). Eles são responsáveis por controlar as transições nas animações.
Clique no símbolo de mais (+) para adicionar um novo parâmetro. Ele será do tipo "bool" e terá o nome "estaParado":



Como é de se imaginar, este parâmetro irá gerenciar se a animação do personagem parado deve ser executada ou não.
Agora crie mais outros dois parâmetros também do tipo bool com os nomes "estaAndando" e "estaAtacando":



Vamos então condicionar a transição "parado >> andando" clicando na transição referida.
Através do inspector procure pela propriedade "Conditions" e selecione o parâmetro "estaAndando":



Dessa forma iremos controlar o momento em que a animação do personagem andando deverá ser executada, ou seja, apenas quando o parâmetro "estaAndando" estiver verdadeiro. Controle este, inclusive, que faremos via código.
Agora na transição "andando >> parado" faça o mesmo, só que desta vez o parâmetro é "estaParado":



Faça agora as transições de "parado" para "atacando", sendo o parâmetro condicional "estaAtacando" e mais uma transição de "atacando" para "parado", tendo como parâmetro "estaParado".
Depois, faça com que as animações de ataque sejam exibidas em sequência, criando transições entre elas, bastando que o parâmetro "estaAtacando" seja o condicional para a reprodução dessas animações. Também faça com que todas as animações de ataque tenham transições para ''parado'' com o parâmetro "estaParado" em verdadeiro. Para que as animações de combate voltem a se repetir caso o player continue atacando, faça uma transição da última animação de ataque para a primeira, com o parâmetro "estaAtacando" em verdadeiro.
No final, você terá um fluxo como este:



Dê play e veja que apesar de termos o fluxo completo criado, o personagem só executa sua animação parado. Isso ocorre porque devemos gerenciar os estados dos parâmetros dentro do controller, e faremos isto através de código:

Em C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AnimationManager : MonoBehaviour {
	Animator anim;

	void Start () {
		anim = GetComponent<Animator> (); 
	}

	void Update () {
		var estaMovendo = Input.GetAxis ("Vertical");
		if (estaMovendo != 0) {
			anim.SetBool ("estaAndando", true);
			anim.SetBool ("estaParado", false);
		} else {
			anim.SetBool ("estaAndando", false);
			anim.SetBool ("estaParado", true);
		}

		if (Input.GetButtonDown ("Fire1")) {

			anim.SetBool ("estaAtacando", true);
			anim.SetBool ("estaParado", false);

		} else {

			anim.SetBool ("estaAtacando", false);
		}
	}
}


Em JavaScript
#pragma strict

public class AnimationManager extends MonoBehaviour{

var anim: Animator;

function Start(){

anim = gameObject.GetComponent("Animator") as Animator;
}

function Update () {

var estaMovimentando: float = Input.GetAxis("Vertical");
      if (estaMovimentando != 0){
             anim.SetBool("estaAndando", true);
             anim.SetBool("estaParado", false);
} else {
       anim.SetBool("estaAndando", false);
       anim.SetBool("estaParado", true);
}

if (Input.GetButton("Fire1")){
           anim.SetBool("estaAtacando", true);
           anim.SetBool("estaParado", false);
} else {
      anim.SetBool("estaAtacando", false);
}
	
}
}



Perceba que na linha "var estaMovendo = Input.GetAxis ("Vertical");" não estamos fazendo com que o personagem de fato se movimente (ande), apenas estamos armazenando uma validação se o jogador está pressionando as teclas de movimento pela vertical (baixo e cima OU s e w).
Também estamos referenciando através do objeto "anim" o componente "Animator" para que possamos ter acesso aos seus parâmetros através do método "SetBool", que pede como argumento o nome do parâmetro e o estado em que ele deve ficar, no caso aqui, true ou false.
Então o código basicamente checa se o jogador está pressionando os botões dos eixos verticais, caso sim, ele faz com que o parâmetro "estaAndando" fique true e "estaParado" fique false, e se ele soltar desses botões, o personagem ficará parado e o parâmetro "estaParado" fica true, enquanto "estaAndando" fica false.
Para os ataques, basta verificar se o jogador está pressionando o botão de ataque (lado esquerdo do mouse), caso sim, o parâmetro "estaAtacando" fica true e "estaParado" fica false (para não acontecer conflitos) e quando soltar esse botão, "estaAtacando" ficará false. Algo bem lógico, né? Por fim, adicione este script ao personagem.

Dê play e teste o jogo: Perceba que mesmo pressionando os botões corretos a animação demora a acontecer, só depois que ela termina, a próxima inicia. Como arrumar isso?
Nas transições "parado >> andando", "andando >> parado" e "parado >> atacando" através do inspector, desmarque a opção "Has exit time" que faz com que a próxima animação só seja executada se a anterior tiver terminado:



Desmarcando essa propriedade, independente do frame da animação corrente, ela será interrompida se o parâmetro for satisfeito.
Agora teste novamente o jogo e veja que agora está tudo funcionando corretamente:



Finalização:
E é isso pessoal, este tutorial foi mais focado na importação de animações para engine através do mixamo.com e divulgação do site, em breve trarei outros tutoriais mais específicos da Unity, se gostarem deste!
Até mais.


Citação de: makergame2000 online 09/04/2018 às 20:28
Por acaso não conhecia o mixamo

Boa partilha

Fico feliz em poder ajudar!  :blink:

Pô, baita tutorial e está passando quase despercebido. Nunca tinha ouvido falar nesse Mixamo, muito obrigado pela sugestão. Eu ainda imaginava que só era possível fazer animações para modelos em 3D com aqueles belos modelitos cheios de sensores. Muito bom mesmo saber disso aí. Apesar da Unity já não rodar mais no meu note, pretendo brincar com ela no futuro, quando tiver um PC decente. o/