Visão Geral do Unity
Autor: Jogos e Mais Jogos | Publicado: 2011-12-03T06:20:00-08:00

Com a adesão crescente de novos usuários à&nbsp;Unity, tanto aqui na comunidade quanto mundo á fora, busco através deste tutorial expressar uma visão geral sobre a engine, suas ferramentas e ajudar os aventureiros e curiosos a terem uma experiência prévia de uma rotina de trabalho no ambiente da ferramenta.<!--[if gte vml 1]><v:shapetype
 id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t"
 path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f">                                               <v:shape id="Imagem_x0020_2" o:spid="_x0000_s1031" type="#_x0000_t75"
 alt="Unity 3D - Visão Geral_html_4b9a674a"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_4b9a674a.png"
 style='position:absolute;margin-left:143pt;margin-top:0;width:183pt;height:183pt;
 z-index:1;visibility:visible;mso-wrap-style:square;mso-wrap-distance-left:0;
 mso-wrap-distance-top:0;mso-wrap-distance-right:0;mso-wrap-distance-bottom:0;
 mso-position-horizontal:right;mso-position-horizontal-relative:text;
 mso-position-vertical:absolute;mso-position-vertical-relative:line'
 o:allowoverlap="f" o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image001.png"
  o:title="Unity 3D - Visão Geral_html_4b9a674a"/>   <![endif]--><!--[if !vml]--><!--[endif]-->Este tutorial é uma compilação de conceitos e conhecimentos básicos que todo desenvolvedor em Unity precisa ter antes de partir para qualquer tipo de projeto e graças à esplêndida estrutura em que a Unity é desenhada você pode facilmente produzir enquanto aprende. Pensando nisso, vejamos o que será explorado neste pequeno tutorial:<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Entendo Assets, GameObjects e Components.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Importando Skinned Meshes e trabalhando com animações.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Conhecendo melhor o Builtin Controller Component.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Entendendo Unity's JavaScript, suas funções e co-rotinas.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Trabalhando com Classes, Helper Functions e código Frame-Dependente.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Colocando tudo em prática.O que você já precisa dominar para melhor aproveitamento e entendimento deste tutorial:<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Ser familiarizado com a interface do Unity Editor.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Possuir algum personagem 3D animado ou saber como produzir um em seu software de preferência.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Ter acesso aos guias e manuais oficiais da Unity para referência.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->Ter um conhecimento mínimo da estrutura e programação em JavaScript.<!--[if gte vml 1]><v:shape id="Imagem_x0020_1"
 o:spid="_x0000_i1031" type="#_x0000_t75" alt="Tela principal do Unity"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_m2929a931.jpg"
 style='width:411.75pt;height:324.75pt;visibility:visible;mso-wrap-style:square'
 o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image003.jpg"
  o:title="Tela principal do Unity"/> <![endif]--><!--[if !vml]--><!--[endif]-->Sendo assim, vamos lá:1. Entendo Assets, GameObjects e Components:1.1 Assets:Assets, se você já andou explorando as funcionalidades e documentação, já deve ter em mente que os Assets são os arquivos físicos de seu projeto. Não há nenhum segredo aqui, todos os seus modelos 3D, arquivos de áudio, scripts, etc e etc que precisam ser estocados em disco são parte desta classe de seu projeto, os recursos com o qual você irá trabalhar encima de seu projeto.<!--[if gte vml 1]><v:shape id="Imagem_x0020_2"
 o:spid="_x0000_i1030" type="#_x0000_t75" alt="Assets do seu projeto"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_61909a1.jpg"
 style='width:129pt;height:183pt;visibility:visible;mso-wrap-style:square'
 o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image004.jpg"
  o:title="Assets do seu projeto"/> <![endif]--><!--[if !vml]--><!--[endif]-->Antes que um Asset possa ser utilizado é necessário que você tenha um projeto criado e adicione o arquivo desejado dentro da pasta Asset na pasta raiz do projeto.Uma funcionalidade incrível da Unity é que você pode trabalhar, por exemplo, em suas cenas 3D e apenas clicando save no modelador o resultado é automaticamente atualizado na Unity, você apenas assiste a engine re-compilando a cena e logo em seguida o resultado pode ser facilmente visualizado no Scene View.Dê uma olhada no guia básico da Unity para um melhor entendimento.1.2 GameObjects:<!--[if gte vml 1]><v:shape id="Imagem_x0020_3"
 o:spid="_x0000_i1029" type="#_x0000_t75" alt="Game Objects da cena atual"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_63c265b0.jpg"
 style='width:138.75pt;height:183pt;visibility:visible;mso-wrap-style:square'
 o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image005.jpg"
  o:title="Game Objects da cena atual"/> <![endif]--><!--[if !vml]--><!--[endif]-->Todo objeto que faz parte do mundo 3D de sua cena e possui um Component “Transform” é um GameObject. Um Transform é apenas um componente ligado ao objeto que indica que o mesmo tem volume, escala ou apenas se localiza em algum ponto no mundo 3D de sua cena, são as básicas informações XYZ. Ao trabalhar na Unity, você geralmente usa um Asset como base para criar seu GameObject e com o auxilio de Components vai adicionando funcionalidades, com o GameObject implementado da maneira que você deseja, é sempre boa prática converter o GameObject em um Prefab para melhor organização, melhor performance e facilidade de re-uso de seus objetos entre os vários leveis que pode ter o seu game.Prefabs são outra ferramenta de destaque extremamente úteis e poderosas na Unity. Consulte a documentação para melhor informação.1.3 Componentes<!--[if gte vml 1]><v:shape id="Imagem_x0020_4"
 o:spid="_x0000_i1028" type="#_x0000_t75" alt="Componentes de um Game Object"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_499cabbf.jpg"
 style='width:146.25pt;height:183pt;visibility:visible;mso-wrap-style:square'
 o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image006.jpg"
  o:title="Componentes de um Game Object"/> <![endif]--><!--[if !vml]--><!--[endif]-->Sem eles é impossível dar vida á qualquer objeto que faça parte de seu cenário. Os Components são a essência de como as coisas na Unity funcionam, são a maior expressão das facilidades de trabalho que a engine oferece. Scripts são Components, objetos e efeitos de física, partículas, áudio e etc são todos Components que podem ser adicionados ao seu GameObject para faze-lo se comportar dar maneira que você deseja no game. É importantíssimo ter uma visão clara de como os Components funcionam e como se relacionam entre si.Mais sobre isso será falado durante a seção de programação, mas se você sente que não entende realmente o que exatamente são essas coisas, procure pensar que Components são “Itens” que formam um item ainda maior, seu objeto na cena, e que eles controlam todas as características do objeto no game. Um GameObject sem Components é um objeto sem característica alguma, por isso não pode ser manipulado de forma alguma e provavelmente é um objeto inútil para o seu projeto neste ponto.Simplificando, Components são propriedades que tornam seus GameObjects únicos através da combinação entre as ferramentas providas pela Unity e os Assets que você produz. É assim justo dizer que quanto melhor forem os Assets que você produz, melhores serão seus GameObjects e maiores as capacidades de seus Components de realizar exatamente tudo que você deseja extrair deles.2. Importando Skinned Meshes e trabalhando com animaçõesVocê já conhece bem a interface da Unity e agora tem um entendimento mais claro dos como e por quê seus objetos funcionam. Sendo assim, partiremos para um pequeno experimento prático, importar um personagem animado e dar funcionalidade á ele.2.1 O Personagem<!--[if gte vml 1]><v:shape id="Imagem_x0020_5"
 o:spid="_x0000_i1027" type="#_x0000_t75" alt="Personagem usado como exemplo"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_m25a13245.jpg"
 style='width:107.25pt;height:183pt;visibility:visible;mso-wrap-style:square'
 o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image007.jpg"
  o:title="Personagem usado como exemplo"/> <![endif]--><!--[if !vml]--><!--[endif]-->Se você não possui um personagem animado, divirta-se, crie um! :)Para este personagem em questão que eu usarei, existem algumas notas que devem estar em mente.Eu tenho a intenção de utilizar efeitos de física real no personagem, por isso neste caso há duas versões dele, uma sem Skin com todas as partes do corpo separadas em pedaços para serem adicionadas componentes físicos e gerar um efeito rápido e fácil diferenciado de “ragdoll” onde o personagem explode ao morrer.E a versão convencional com a Skin e animações como de costume.Este é um caso específico do meu trabalho em questão, você não é obrigado a fazer um personagem da mesma maneira, use sua liberdade e imaginação.2.2 Implementando o Personagem<!--[if gte vml 1]><v:shape
 id="Imagem_x0020_3" o:spid="_x0000_s1030" type="#_x0000_t75" alt="Personagem já no Unity"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_m8253629.jpg"
 style='position:absolute;margin-left:443pt;margin-top:0;width:483pt;height:266.25pt;
 z-index:2;visibility:visible;mso-wrap-style:square;mso-wrap-distance-left:0;
 mso-wrap-distance-top:0;mso-wrap-distance-right:0;mso-wrap-distance-bottom:0;
 mso-position-horizontal:right;mso-position-horizontal-relative:text;
 mso-position-vertical:absolute;mso-position-vertical-relative:line'
 o:allowoverlap="f" o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image008.jpg"
  o:title="Personagem já no Unity"/>   <![endif]--><!--[if !vml]--><!--[endif]-->Por motivos de Pipeline, já utilizo o formato FBX á um bom tempo, eu continuo usando FBX mesmo na Unity, por conveniência.Você pode utilizar o formato que preferir e se adaptar melhor.Bom, após um tempo relativamente grande, você modelou, texturizou, animou seu querido personagem e está pronto pra faze-lo mandar ver na Unity. Apesar das facilidades que a Unity oferece, você precisa ter em mente que certas convenções devem ser seguidas.Antes de qualquer coisa, adicione seu modelo em qualquer diretório dentro da pasta Assets do seu projeto, a Unity irá detectar o arquivo e ele aparecerá na lista do Inspector com todas suas opções de importação. Não mecha em absolutamente nada, click e arraste o modelo da lista do Project View para a Scene View e veja o que acontece. Seu personagem aparece na cena sem problemas? Ótimo, você é um cara de sorte! Click Play e rode o game, veja se as animações rodam normalmente como esperado.As animações estão ok? Ótimo, você é mesmo um cara de sorte! :)Ao arrastar o personagem para a cena, ele está distorcido, como se os bones não estivessem nas posições corretas ou coisa semelhante? Opa, volte ao seu modelador 3D e reveja seus conceitos, evite criar uma hierarquia muito complexa de parents e childs, grupos e sub grupos quando se trata de um personagem animado.Ao arrastar o personagem para a cena, o modelo parece estar ok, mas as animações simplesmente não tocam ou existe algo de errado com elas, como se suas animações não estivessem ali?Opa, volte ao seu modelador 3D e reveja novamente seus conceitos, se você tem conhecimento básico sobre animação deve saber que as animações de controladores e parentes dos bones, efeitos físicos, driven keys e etc, não são automaticamente adicionados aos bones do seu modelo no momento da exportação, por isso, se for o caso de haver animações faltando ou animações faltando pedaços, você precisa ter certeza de que todos os movimentos que faz está gerando animation keys nos bones do personagem ou seja, você precisa usar a solução “Bake Animations”. Você pode fazer isso diretamente na Unity simplesmente acionando a check-box de mesmo nome no Importer do seu modelo ou se quiser mais controle sobre os resultados, faça isso você mesmo no modelador, os resultados são mais fáceis de serem mantidos da maneira que você exatamente quer. Se você não sabe como fazer um “bake” em suas animações, consulte a documentação do seu programa ou peça socorro á comunidade lá no fórum da Unity, sempre tem alguém perguntando sobre este tipo de problema.No geral, clicando em Bake Animations na Unity vai resolver seus problemas e muita dor de cabeça se você não gosta de ficar horas otimizando keys no seu modelador 3D.Após ajustadas as configurações de importação, seu personagem é animado da maneira que você espera? Ótimo, é hora de prepara-lo para o futuro que o reserva, no Importer do seu modelo, clicando no arquivo importado no Project View ficará visível no Inspector, você verá que existe uma variedade grande de opções e propriedades. Seja um bom amigo com você mesmo e pesquise na documentação cada uma dessas características e opções para ter uma visão mais intuitiva e verdadeira do que cada uma delas possa vir a ser.Mais abaixo no Inspector, existe um pequeno grupo que é acionado quando você seleciona a opção “Split Animations”. Click nessa opção e você terá acesso a ferramenta mais simples da terra para criar clips de animações. Você pode dar um nome aos clips e definir o início e fim da animação, seu WrapMode e etc de maneira rápida, fácil e visual.Neste ponto, é extremamente recomendável criar um Prefab para seguir seu trabalho, você não pode trabalhar diretamente encima do Asset do seu personagem por isso é boa prática criar um GameObject com seu personagem, apenas arraste ele do Project View para a Scene View, no menu Assets click em Create New &gt; Prefab, renomeie o Prefab com o nome que quiser e arraste seu personagem da Scene View para cima do Prefab. Pronto, você tem uma instância totalmente reutilizável do seu personagem em que qualquer mudança no Inspector afetará todas as cópias do objeto em sua cena.Após configurar seus clips, seu personagem está pronto para ser animado in-game... Mas hey, e agora? Como se anima o personagem, pergunta-se o afobado aprendiz...A resposta para isso se resume á uma palavra – Scripts!Mas antes, precisamos ter uma ideia mais aprofundada do que exatamente vamos animar. É uma boa hora para pesquisar sobre o Character Controller Component!3. Conhecendo melhor o Builtin Controller Component<!--[if gte vml 1]><v:shape
 id="Imagem_x0020_4" o:spid="_x0000_s1029" type="#_x0000_t75" alt="Unity 3D - Visão Geral_html_1b95013d"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_1b95013d.jpg"
 style='position:absolute;margin-left:143pt;margin-top:0;width:183pt;height:102.75pt;
 z-index:3;visibility:visible;mso-wrap-style:square;mso-wrap-distance-left:0;
 mso-wrap-distance-top:0;mso-wrap-distance-right:0;mso-wrap-distance-bottom:0;
 mso-position-horizontal:right;mso-position-horizontal-relative:text;
 mso-position-vertical:absolute;mso-position-vertical-relative:line'
 o:allowoverlap="f" o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image009.jpg"
  o:title="Unity 3D - Visão Geral_html_1b95013d"/>   <![endif]--><!--[if !vml]--><!--[endif]-->Á primeira vista você deve estar imaginando que este componente é responsável pelo controle das animações de seu personagem durante a execução de seu game, certo... Errado! :PO Component responsável pelas animações, você já passou por ele, seus Animation Clips estão prontos, lembra? A partir daí você pode animar seu personagem através de qualquer script; Mas é interessante analisar a relação restrita entre o Controller, que controla a interatividade entre o jogador e a jogabilidade estabelecida por você, no caso o controle do personagem em questão. O Controller Component existe para facilitar a sua vida na hora de identificar ações e inputs tanto do player quanto do ambiente que cerca seu personagem para uma interação funcional mais rápida prática e intuitiva.Sem essa belezinha você teria deliciosas dores de cabeça para conseguir fazer seu personagem interagir com o resto dos objetos no game e responder aos comandos do jogador. Existe também uma variação mais complexa de Controller, totalmente baseada em física real, mas é um tópico muito nex-gen e avançado demais pra mim no momento e não é meu foco neste tutorial, vamos examinar inicialmente o Controller básico. Se você ainda não leu a respeito deste componente na documentação, esta é a hora.Após ler a documentação, você agora deve saber bem que um Controller basicamente permite que você dê interatividade ao objeto em que o Component está ligado de maneira que esse objeto interaja com o ambiente físico ao redor. Baseado neste fundamento, você pode ter certeza, se você nunca trabalhou com física real antes, ou você aprende&nbsp;um pouco sobre física ou aprende muito sobre física&nbsp;por que a Unity se aproveita ao máximo de todas as formas de manipulação física e estudar um pouco a respeito desta matéria é bastante saudável para facilitar sua vida. Na Unity você irá programar como nunca voltado á interatividade com física real, mesmo que o componente em questão não seja baseado em física. Por mais que seja um tanto incômodo precisar fazer certos cálculos para atingir certos resultados por conta da física, cedo ou tarde você acaba percebendo que esta forma de trabalho diminui de maneira gritante a quantidade de código que você precisa para realizar efeitos complexos e poderosos de mesmo nível que qualquer game comercial existente no mercado.Não vou entrar em extremos detalhes aqui por que seria redundante ficar citando o que já é muito bem explicado na documentação, mas ao trabalhar com Character Controllers, tome sempre um cuidado especial com Physical Materials e com as propriedades do Controller, Height e Skin Width.É aconselhável sempre manter a propriedade “Min Move Distance” em zero, a não ser que você tenha mesmo um bom motivo para não faze-lo.Todos scripts que forem criados com intenção de manipularem a interatividade do personagem farão referência á este componente de alguma forma então, antes de prosseguir, faça os ajustes que achar necessário, experimente bastante com cada propriedade do componente e personifique da maneira que achar melhor.Com o Controller Component adicionado ao seu personagem, ao seleciona-lo você já deve ter notado que aparece um “Capsule Collider” ligado ao mesmo. Ajuste a posição e volume do Collider da maneira que puder de modo que ele represente bem o volume geral do corpo de seu personagem.Para testes, crie uma Box com um Collider Component, modifique sua escala e a utilize como chão, click Play e verifique se os pés de seu personagem não estão flutuando ou afundando no chão, faça os ajustes que achar necessários para ter uma colisão refinada entre seu personagem e os objetos que virem a existir no seu cenário. Quando atingir o resultado que deseja, você pode sempre adicionar as mudanças ao Prefab do Personagem se houver um. Isso afeta todas as cópias do seu Personagem, independente de qual cenário você esteja trabalhando. Após estes pequenos ajustes, estamos prontos para começar a programar.Você pode escolher a linguagem de suporte que achar melhor, eu prefiro JavaScript :)4. Entendendo Unity's JavaScript, suas funções e co-rotinas<!--[if gte vml 1]><v:shape
 id="Imagem_x0020_5" o:spid="_x0000_s1028" type="#_x0000_t75" alt="Unity 3D - Visão Geral_html_m6ceef8a8"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_m6ceef8a8.jpg"
 style='position:absolute;margin-left:80.75pt;margin-top:0;width:120.75pt;
 height:183pt;z-index:4;visibility:visible;mso-wrap-style:square;
 mso-wrap-distance-left:0;mso-wrap-distance-top:0;mso-wrap-distance-right:0;
 mso-wrap-distance-bottom:0;mso-position-horizontal:right;
 mso-position-horizontal-relative:text;mso-position-vertical:absolute;
 mso-position-vertical-relative:line' o:allowoverlap="f" o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image010.jpg"
  o:title="Unity 3D - Visão Geral_html_m6ceef8a8"/>   <![endif]--><!--[if !vml]--><!--[endif]-->Lembre-se que a estrutura aqui é JavaScript, para C# existem pequenas diferenças que devem ser levadas em conta ao programar, se você está iniciando em Unity como eu, é extremamente recomendável começar com JavaScript ao invés de C# pois a comunidade dá muito mais suporte a JavaScript na prática.Antes de entrarmos em detalhes, é importante ressaltar que a Unity tem como expectativa assumir que você, como programador, siga as convenções estabelecidas para programação na ferramenta. É sempre importante lembrar que a engine espera que você siga os padrões de nomenclatura para funções e variáveis, isso não é exatamente obrigatório, você pode não seguir nada disso se quiser, mas no fim das contas você apenas acaba gerando problemas a si próprio. Tendo isso em mente, vejamos as convenções adotadas na Unity mais importantes que são adotadas por toda a comunidade que busca sempre utilizar a ferramenta com eficiência e clareza.4.1 Nomeando FunçõesQuando criar uma função, lembre-se de que o nome de cada função deve começar com um caractere legal e sempre em letra maiúscula. Sabendo disso e seguindo esta padronização, lhe salvará uma vida de problemas e bugs que você mesmo escreveu e não consegue resolver pelo simples fato de não ter seguido uma convenção tão simples.Se a função é um conjunto de várias palavras, você pode optar por usar underlines se quiser, mas é aconselhável apenas seguir o padrão, como por exemplo, MyFunctionName(). Assim quando um problema surgir no debug e apontar para um identificador, você tem certeza absoluta de que o caso se trata de uma função e não qualquer outro tipo de dados.4.2 Nomeando VariáveisAssim como na criação de uma função, é boa prática seguir o padrão estabelecido pela comunidade e desenvolvedores da engine, a simples diferença aqui é que nomes para variáveis sempre devem iniciar com um caractere legal em letra minúscula. Exemplo, minhaVariavel : int;4.3 FunçõesEste ponto é onde a coisa pode complicar de início para programadores que não estão acostumados a seguir o tipo de lógica adotado na Unity. A engine, por padrão, faz todo o trabalho sujo de controle do software, execução, loops, carregos e despejos, etc e etc. Sendo assim, ela trabalha com funções padronizadas que todos os scripts que você escreva irão utilizar uma ou outra de alguma forma.Por exemplo, na Unity você não cria um loop principal para a execução do seu game, pois ele já está lá antes mesmo de você começar a programar. Você apenas precisa chamar uma “instância” da função responsável pelo loop, no caso Update().Isso vai parecer muito confuso no início, você começa a se perguntar, ao criar vários scripts com a mesma função, “qual desses updates é o principal?”... O caso é que toda função que você criar com o nome de Update(), serão todas ao mesmo tempo o seu loop principal. Não me pergunte como a engine faz isso, mas ao compilar seus scripts a Unity detecta todas as instâncias das funções com nome que ela já conhece, transforma todas as funções em uma única função e seu código está pronto para rodar. O que é ainda mais incrível é que ela faz isso mesmo com seu projeto aberto no editor, não é necessário compilar nada, a engine faz tudo sozinha, você apenas clica Play!Vejamos uma relação das funções e métodos padronizados mais importantes que você usará com frequência:4.4 Function Awake(){...}:Essa função, se existente em seu script, é executada sempre que o script é carregado na memória. Mesmo que você não a chame em momento algum, essa função será sempre executada, basta declara-la e todas as ações que você definir na função serão executadas imediatamente no mesmo momento em que o GameObject que contém o script for carregado. Não se faz uma chamada para esse tipo de função, ela apenas é declarada.Geralmente essa função é utilizada somente para captura de valores para variáveis recém-declaradas. Consulte a documentação para maiores informações.4.5 Function Start(){...}:Essa função, se existente em seu script, não é executada assim que seu script é carregado, mas ela atua de maneira muito interessante.Você não precisa chamar esta função de lugar algum, ela será automaticamente executada uma única vez antes que qualquer loop do seu script seja executado pela primeira vez, ou seja, antes do primeiro loop.4.6 Function Update(){...}:Essa função, se existente em seu script, é sempre executada á cada frame. Você não precisa fazer nenhum tipo de referência ou chamada, ela apenas será executada como forma de loop principal do seu script, não necessariamente do seu programa, mas de tudo que é executado no script em questão.4.7 Function FixedUpdate(){...}:Essa função é uma variante de Update(), é um loop dedicado á proporcionar melhor funcionalidade para qualquer efeito diretamente ligado á RigidBodies. Você pode tanto ter uma FixedUpdate() quanto uma Update() no mesmo script, os loops diretamente ligados á execução do game são sempre interligados entre si e a execução de um loop não interfere na execução de outro.4.8 Function LateUpdate(){...}:Essa função, também variante de Update() é um loop para chamada específica de ações que você deseja executar somente quando todas as instancias de Update() já foram executadas. É muito útil para a implementação de animações via script, restrições de movimento ou posição de objetos, etc.Existem muitos outros loops pré-determinados pela Unity sempre estabelecidos de maneira que possam agilizar seu trabalho. Consulte a documentação e pesquise sobre loops distintos existentes em várias classes da engine. Procure se familiarizar com a relação geral desses loops entre si, mas concentre-se apenas em dominar as funções descritas acima, sem um domínio claro do uso dessas funções e de como elas podem ser utilizadas em seu projeto, todo o resto se torna uma pilha de informações sem sentido no momento em que você for programar qualquer coisa com a Unity.5. Trabalhando com Classes, Helper Functions e código Frame-Dependente<!--[if gte vml 1]><v:shape
 id="Imagem_x0020_6" o:spid="_x0000_s1027" type="#_x0000_t75" alt="Unity 3D - Visão Geral_html_3aab4818"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_3aab4818.jpg"
 style='position:absolute;margin-left:143pt;margin-top:0;width:183pt;height:84pt;
 z-index:5;visibility:visible;mso-wrap-style:square;mso-wrap-distance-left:0;
 mso-wrap-distance-top:0;mso-wrap-distance-right:0;mso-wrap-distance-bottom:0;
 mso-position-horizontal:right;mso-position-horizontal-relative:text;
 mso-position-vertical:absolute;mso-position-vertical-relative:line'
 o:allowoverlap="f" o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image011.jpg"
  o:title="Unity 3D - Visão Geral_html_3aab4818"/>   <![endif]--><!--[if !vml]--><!--[endif]-->Um fato curioso sobre trabalhar com a Unity é que você vai precisar utilizar classes em casos relativamente raros em seu projeto, ao contrário de muitas outras engines ou plataformas existentes por aí. Isso se dá pelo fato de que a Unity é tão bem projetada que qualquer coisa que você queira criar provavelmente já se encaixa como descendente de alguma classe já existente na Unity então a criação de classes em seu game raramente se tornará uma rotina.Apesar disso, existem casos em que a criação de classes será extremamente útil e tornará seu script muito mais maleável e poderoso. O uso de classes também pode facilitar a leitura de seu código, tornando sua escrita mais elegante e muito bem organizada de modo que em um trabalho feito por uma equipe, a criação de co-rotinas por outro programador fica muito agradável de forma que seu colega não precisa realmente dominar totalmente todos os pormenores da classe que você escreveu. Helper functions, co-rotinas, são inicialmente uma ferramenta chave para manter a organização de seu código, tornando-o ainda mais legível que de costume e ajuda a facilitar a procura por bugs que cedo ou tarde inevitavelmente acabam surgindo durante sua produção. Outra característica importante sobre co-rotinas é que elas abrem um outro leque de possibilidades como as tão importantes funções dependentes de tempo ou frame-rate.5.1 ClassesA Unity já disponibiliza uma lista robusta de classes que você usa e abusa, mas é interessante ter a possibilidade de criar classes customizadas inteiramente dedicadas á um tipo específico de objeto em seu game, por exemplo, uma classe dedicada somente ao controle do seu personagem, outra classe dedicada somente á execução de animações do personagem, outra classe que ativa triggers que otimizam a interatividade de seu personagem com o ambiente, etc.5.2 Helper FunctionsA primeira funcionalidade de importância real que você vai encontrar para o uso obrigatório deste tipo de funções é a possibilidade de utilizar, a partir dessas co-rotinas, funções que derivam da classe “Yield”. Funções do tipo Yield não podem ser chamadas de loops principais como Update() por que elas tem como característica interromper a execução do loop, veja bem, do loop que chama a função, não seu programa como um todo.Essa distinção pouco comum entre funções na Unity proporciona uma maleabilidade incrível na manipulação de seu código. Você pode interromper partes da execução de um loop enquanto que outra parte do mesmo loop pode continuar sendo executada normalmente. Tal funcionalidade é muito útil para muitas situações que possam surgir, mas com certeza este tipo de função é largamente utilizado para um controle preciso e refinamento de animações e timing que você irá se deparar cedo ou tarde.5.3 Código Frame-DependenteA Unity já disponibiliza funções plenas para manipulação e checagem de tempo que estão sempre a disposição para lhe dar suporte no momento em que precisar. Se você não está acostumado a utilizar o conceito de Delta-Time, consulte a documentação da classe “Time” na referência de scripting. Você vai encontrar variáveis muito úteis como Time.deltaTime que podem facilitar suas animações via script de maneira suave e limpa.6. Colocando tudo em prática<!--[if gte vml 1]><v:shape
 id="Imagem_x0020_7" o:spid="_x0000_s1026" type="#_x0000_t75" alt="Unity 3D - Visão Geral_html_m68f6501c"
 href="http://www.pontov.com.br/site/images/stories/artigos/Unity-3D---Viso-Geral_html_m68f6501c.jpg"
 style='position:absolute;margin-left:95pt;margin-top:0;width:135pt;height:180pt;
 z-index:6;visibility:visible;mso-wrap-style:square;mso-wrap-distance-left:0;
 mso-wrap-distance-top:0;mso-wrap-distance-right:0;mso-wrap-distance-bottom:0;
 mso-position-horizontal:right;mso-position-horizontal-relative:text;
 mso-position-vertical:absolute;mso-position-vertical-relative:line'
 o:allowoverlap="f" o:button="t">    <v:imagedata src="file:///D:\DOCUME~1\Tiago\LOCALS~1\Temp\msohtmlclip1\01\clip_image012.jpg"
  o:title="Unity 3D - Visão Geral_html_m68f6501c"/>   <![endif]--><!--[if !vml]--><!--[endif]-->Agora que já temos uma visão mais ampla das características da engine que envolvem a implementação de um personagem interativo na Unity, vamos arregaçar as mangas e botar as mãos na maça! :)Nota: Meu projeto em particular se trata de um platformer, e no site da Unity você pode encontrar muito material de referência que estou usando como guia base tanto para este tutorial quanto para o desenvolvimento do meu projeto pessoal. Sinta-se sempre compelido a baixar tudo que o site da Unity oferece e examine de cabo á rabo todos os scripts que caírem em suas mãos. No tutorial básico para um 2D Platformer, você poderá perceber que existem muitas funções implementadas pelo Flashbang Studios que também são usadas aqui de forma muito semelhante, se não idênticas em alguns casos.Lembre-se de que nem tudo se trata de autoria, muita coisa se trata de pesquisa. Não trate o hábito de pesquisar como algo ruim, isso apenas vai lhe impedir de compartilhar com gente muito mais experiente e com conhecimento muito mais profundo do que o seu. Mantenha a mente aberta! :)6.1 Importe o Asset de seu personagemCrie um GameObject, crie um Prefab e estamos prontos para começar a botar as ideias em prática. Por enquanto não se preocupe com esse Prefab, apenas seguimos em frente com nosso personagem existente na cena.6.2 Crie uma pasta no Project ViewApós criar a paste, renomeie para Scripts. Em seguida, selecione essa mesma pasta, vá até Assets &gt; Create &gt; JavaScript. Um script descendente da classe MonoBehavior será criado na paste selecionada. Selecione o script criado e renomeie com o mesmo nome de seu personagem, apenas para melhor organização.6.3 Criando um ComponenteAgora que já temos um Component que podemos trabalhar encima de nosso personagem, na Hierarchy View selecione seu personagem, vá até Components &gt; Create New &gt; NomeDeSeuScript. Notou como o script que criou aparece instantaneamente no menu? Coisa linda não? Selecione o script de seu personagem, preste atenção nas propriedades no Inspector de seu personagem, ele agora também lista o componente recém-adicionado.Seu Script é um componente como qualquer outro ligado ao personagem, se quiser você pode aplicar as mudanças do GameObject ao seu Prefab.Selecione a opção Edit no Component Script de seu personagem ou dê um duplo clique no script no Project View, a Unity irá iniciar seu editor padrão para a edição de scripts. Você pode utilizar qualquer editor que quiser para isso, o editor de scripts é sempre um programa externo, você pode também customizar de modo forçado as opções do editor padrão, mas isso já é conteúdo para um outro tutorial, nos manteremos focados ao que realmente importa aqui.6.4 Editando um ScriptAo abrir seu script para edição, por padrão a Unity já o cria com uma função Update() vazia. Isso, por enquanto, não é muito útil. Agora, vamos parar e pensar um pouco... O que queremos fazer aqui?“-Bota essa budega pra funfá, e para de blahblah”, diz o afoito aprendiz.Bom, sem entendermos bem o que exatamente queremos fazer, não será possível fazermos exatamente nada de útil ou conciso então vamos nos concentrar em um único conceito e trabalhar encima disso...Controle de Personagem? Animação? GamePlay?&nbsp;
Tá legal vamos animar nosso personagem, já que isso parece ser o mais lógico a ser feito primeiro, ao menos é mais lógico para mim.Em seu script, selecione a função Update() vazia e apague. Não precisamos dela agora. Primeiro vamos pensar de modo genérico sobre as ações de nosso personagem. O que ele irá fazer no game? Vai andar? Correr? Pular? Etc.Com isso em mente, já temos algo por onde começar, hora de começar a cuspir variáveis que achamos que podem ser úteis. Lembre-se, se você não conhece um mínimo de JavaScript, ao menos a syntax, você pode ter experiências desagradáveis ao programar. Tenha certeza de que já se sente confortável com a programação nesta linguagem e que sua syntax não pareça algo alienígena. Sendo assim, vamos lá. Criando as variáveis:?
      123456789101112131415      var sneakAnimationSpeedModifier = 1.5;
var walkAnimationSpeedModifier = 2.5;
var runAnimationSpeedModifier = 1.5;
var jumpAnimationSpeedModifier = 2.0;
var jumpLandAnimationSpeedModifier = 3.0;
var getDownAnimationSpeedModifier = 1.5;
var hangTimeUntilFallingAnimation = 0.05;
private var   floorHitFX : AudioClip;  
Cada variável tem um propósito, conforme descrito a seguir:<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->sneakAnimationSpeedModifier: Usaremos esta variável para um controle mais ágil da velocidade em que a animação “Sneak” será executada.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->walkAnimationSpeedModifier: Usaremos esta variável para controlar a velocidade em que a animação “Walk” será executada.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->runAnimationSpeedModifier: Usaremos esta variável para controlar a velocidade em que a animação “Run” será executada.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->jumpAnimationSpeedModifier: Usaremos esta variável para controlar a velocidade em que a animação “Jump” será executada.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->jumpLandAnimationSpeedModifier: Usaremos esta variável para controlar a velocidade em que as animações “Landing” e “Landed” serão executadas.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->getDownAnimationSpeedModifier: Usaremos esta variável para controlar a velocidade em que a animação “Get Down” será executada.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->hangTimeUntilFallingAnimation: Usaremos esta variável para identificar quanto tempo faz que o personagem está em queda livre.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->floorHitFX: Usaremos esta variável do tipo AudioClip para guardar um pointer para o som que queremos tocar quando o personagem atinge o chão de maneira descontrolada. Se isso parecer confuso, consulte a classe AudioClip na documentação.A regra “private”, ao contrário do que parece, não isola sua variável contra acesso de outros scripts. Na verdade deveria, mas sempre existe alguma maneira de acessar uma variável privada se preciso, então é apenas uma questão de isolar a variável para que ela não esteja amostra no Inspector.Após definir suas variáveis, selecione seu personagem ou Prefab, observe no Inspector como elas se tornaram parte das propriedades do seu script. Essa funcionalidade do Inspector é sem palavras, torna seu trabalho tão dinâmico.6.5 Implementando o PersonagemAgora que temos nossas variáveis, podemos trabalhar encima disso, dando á elas as funcionalidades que buscamos. Com o conceito de controle de nossas animações em mente, vamos iniciar a estrutura básica que coloca em prática os clips de animações que criamos anteriormente na importação do Asset do personagem:?
      12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849      function Start()   {&nbsp;&nbsp;&nbsp;&nbsp;animation.Stop();&nbsp;&nbsp;&nbsp;&nbsp;var jumpingLayer = 1;&nbsp;&nbsp;&nbsp;&nbsp;var afterJumpLayer = 2;&nbsp;&nbsp;&nbsp;&nbsp;var jump = animation["Jump"];
&nbsp;&nbsp;&nbsp;&nbsp;jump.layer = jumpingLayer;&nbsp;&nbsp;&nbsp;&nbsp;jump.speed *= jumpAnimationSpeedModifier;
&nbsp;&nbsp;&nbsp;&nbsp;var jumpFall = animation["Small Fall"];&nbsp;&nbsp;&nbsp;&nbsp;jumpFall.layer = jumpingLayer;
&nbsp;&nbsp;&nbsp;&nbsp;var freeFall = animation["Fall"];&nbsp;&nbsp;&nbsp;&nbsp;freeFall.layer = afterJumpLayer;
&nbsp;&nbsp;&nbsp;&nbsp;var fallImpact = animation["Floor Impact"];&nbsp;&nbsp;&nbsp;&nbsp;fallImpact.layer = afterJumpLayer;&nbsp;&nbsp;&nbsp;&nbsp;fallImpact.speed *= 3;
&nbsp;&nbsp;&nbsp;&nbsp;var fallGetUp = animation["Get Up"];&nbsp;&nbsp;&nbsp;&nbsp;fallGetUp.layer = afterJumpLayer;&nbsp;&nbsp;&nbsp;&nbsp;fallGetUp.speed *= 0.95;
&nbsp;&nbsp;&nbsp;&nbsp;var stayJumping = animation["Stay   Jumping"];&nbsp;&nbsp;&nbsp;&nbsp;stayJumping.layer = afterJumpLayer;
&nbsp;&nbsp;&nbsp;&nbsp;var jumpLanding = animation["Landing"];&nbsp;&nbsp;&nbsp;&nbsp;jumpLanding.layer = afterJumpLayer;&nbsp;&nbsp;&nbsp;&nbsp;jumpLanding.speed *=   jumpLandAnimationSpeedModifier*2.5;
&nbsp;&nbsp;&nbsp;&nbsp;var jumpLand = animation["Landed"];&nbsp;&nbsp;&nbsp;&nbsp;jumpLand.layer = jumpingLayer;&nbsp;&nbsp;&nbsp;&nbsp;jumpLand.speed *=   jumpLandAnimationSpeedModifier;
&nbsp;&nbsp;&nbsp;&nbsp;var run = animation["Run"];&nbsp;&nbsp;&nbsp;&nbsp;run.speed *= runAnimationSpeedModifier;
&nbsp;&nbsp;&nbsp;&nbsp;var walk = animation["Walk"];&nbsp;&nbsp;&nbsp;&nbsp;walk.speed *= walkAnimationSpeedModifier;
&nbsp;&nbsp;&nbsp;&nbsp;var sneak = animation["Sneak"];&nbsp;&nbsp;&nbsp;&nbsp;sneak.speed *= sneakAnimationSpeedModifier;
&nbsp;&nbsp;&nbsp;&nbsp;var getDown = animation["Get Down"];&nbsp;&nbsp;&nbsp;&nbsp;getDown.speed *=   getDownAnimationSpeedModifier;
&nbsp;&nbsp;&nbsp;&nbsp;var smallImpact = animation["Small   Impact"];&nbsp;&nbsp;&nbsp;&nbsp;smallImpact.layer = afterJumpLayer;}  
Note que este bloco de código apenas inicializa as variáveis com os valores desejados. Isso poderia ser feito em qualquer ponto fora da função Start(), mas como queremos ter certeza de que as variáveis serão inicializadas antes que qualquer loop comece a rodar, inicializamos as variáveis desta forma.6.6 Trabalhando com Animações não ProceduraisTrabalhar com animações não procedurais é relativamente simples, então tudo que precisamos é de um punhado de ações e reações controlados por mais um punhado de estruturas baseadas em Cases ou Ifs. Com nossas variáveis inicializadas, só nos resta implementar os resultados no personagem durante a execução do game, então devemos trabalhar na função Update(). Antes disso, criaremos algumas co-rotinas que podem auxiliar algumas tarefas durante a execução das animações:?
      1234567891011121314151617181920212223242526272829303132333435363738      function DidJump()   {&nbsp;&nbsp;&nbsp;&nbsp;animation.Play("Jump");&nbsp;&nbsp;&nbsp;&nbsp;animation.PlayQueued("Small Fall");&nbsp;&nbsp;&nbsp;&nbsp;yield WaitForSeconds(0.225);&nbsp;&nbsp;&nbsp;&nbsp;if (Input.GetButton("Jump"))&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Stay   Jumping");&nbsp;&nbsp;&nbsp;&nbsp;} else {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (GetComponent(PlayerController).isFalling   == false)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Small   Fall");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.Play("Fall");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;yield WaitForSeconds(0.015);&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).canControl =   false;}
function DidLand()   {&nbsp;&nbsp;&nbsp;&nbsp;if (GetComponent(PlayerController).isFalling ==   false)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (animation.IsPlaying("Stay   Jumping"))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.Play("Landing");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Landed");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield   WaitForSeconds(0.15);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).canControl   = true;&nbsp;&nbsp;&nbsp;&nbsp;} else {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Floor   Impact");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Get   Up");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).isFalling   = false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;yield   WaitForSeconds(0.15);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).canControl   = true;&nbsp;&nbsp;&nbsp;&nbsp;}}  
Sobre a função DidJump(): Esta função será utilizada pelo script PlayerController que criaremos logo depois. Basicamente, essa função checa o estado da animação atual e executa a animação desejada assim que o script PlayerController decidir que é o momento certo para estas animações serem executadas.Sobre a função DidLand(): Sempre que o script PlayerController detectar que o personagem pousou de um salto ou caiu em algum lugar, ele irá enviar uma mensagem para este script dizendo que o personagem acabou de atingir o solo e a animação de pouso deve ser tocada.Ao salvar seu script, neste ponto a Unity vai estar se indagando o que viria a ser o componente “PlayerController”. Este é um script que ainda não criamos, por isso seu código ainda não funciona, mas agora precisamos definir a função Update() e então podemos partir para o script que a Unity acusa estar faltando.6.7 Editando a função UpdateNa função Update() nós continuamos o trabalho com as animações, mas com a diferença de que não poderá ser usada nenhuma função “Yield” aqui:?
      1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677      function Update()   {&nbsp;&nbsp;&nbsp;&nbsp;if (GetComponent(PlayerController).GetHangTime()   &lt; hangTimeUntilFallingAnimation)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (GetComponent(PlayerController).headsUp   == false)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (GetComponent(PlayerController).IsMoving())&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Input.GetButton("Action   A"))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (GetComponent(PlayerController).isSneaking   != true)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade   ("Run");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Sneak");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(Input.GetAxis("Vertical")   &lt;= -0.25)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Sneak");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).isSneaking   = true;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade   ("Walk");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).isSneaking   = false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (GetComponent(PlayerController).headsUp   == true)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Get   Down");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).isSneaking   = true;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (GetComponent(PlayerController).isSneaking   == false)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Idle");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!GetComponent(PlayerController).IsMoving())&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Input.GetAxis("Vertical")   &lt;= -0.25)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Get   Down");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).isSneaking   = true;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).isSneaking   = false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetComponent(PlayerController).isSneaking   = true;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (GetComponent(PlayerController).IsMoving()   == false)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Get   Down",0.5);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Sneak",0.5);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (!GetComponent(PlayerController).isSneaking   == true)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Landed");&nbsp;&nbsp;&nbsp;&nbsp;}}  
E assim nossas animações estão prontas para desempenhar seu papel no game.Nessa função existe conteúdo suficiente para um bom tempo de estudo. Deixando um pouco de lado a mecânica de nossas animações, vamos dar uma olhada mais de perto em o que exatamente estas linhas estão fazendo:Antes de tudo, nós verificamos se o personagem não está caindo á tempo suficiente para impedir sua movimentação terrena, e se caso não o estiver, seguimos em frente com as animações, caso contrário significa que precisamos tocar a animação de pouso pois muito em breve ele irá tocar o solo. Verificamos isso através da função GetHangTime() que escreveremos no futuro.Em seguida, verificamos se o personagem não colidiu com algum obstáculo que o force à se manter agachado através da variável headsUp. A implementação desta funcionalidade pode se tornar complexa pois envolve alguns conceitos que talvez não sejam cobertos aqui, por isso talvez seja matéria de um outro tutorial no futuro, quem sabe.Se o personagem estiver ciente de que há algo sobre sua cabeça que o impede de levantar, ele será obrigado à se mover agachado, caso contrário se o botão de corrida estiver pressionado ele poderá correr, caso contrário eles apenas irá andar normalmente. Assim nós tocamos a animação de correr ou andar ou engatinhar somente se o personagem está mesmo se movendo, julgando isso através da função IsMoving() que ainda não foi escrita.Note que as teclas virtuais do meu projeto tem nomes próprios ao invés do padrão criado pela Unity.Se você precisar editar suas teclas virtuais, vá até Edit &gt; Project Settings &gt; Input.6.8 PlayerControllerPartiremos agora para o lado interativo que controla nossas animações com o script PlayerController.Vá até o menu Assets e crie mais um JavaScript, renomeio para “PlayerController”, adicione-o como componente do seu personagem, aplique as mudanças ao Prefab e estamos prontos para programar. Novamente, começamos com a declaração de variáveis:?
      123456789101112131415      var movement   : PlatformerControllerMovement;var jump :   PlatformerControllerJumping;private var controller   : CharacterController;var canControl   = true;var spawnPoint   : Transform;var floorHitFX   : AudioClip;
@System.NonSerializedvar isSneaking   = false;
@System.NonSerializedvar isFalling   = false;
@System.NonSerializedvar headsUp   = false;  
As variáveis são usadas para:<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->movement: Usaremos esta variável como identificador para a classe que determina os movimentos do personagem.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->jump: Usaremos esta variável como identificador para a classe que controla toda mecânica do movimento de pulo do personagem.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->controller: criamos aqui uma instância do Builtin Controller Component que deve ser adicionado ao personagem. Você pode adicionar a linha “ @script RequireComponent(CharacterController) ” ao fim de seu script e assim que ele for adicionado á um objeto, o componente requerido também será adicionado.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->canControl: Usaremos esta variável para permitir ou não que o personagem possa ser controlado pelo jogador. Isso é muito útil para evitar que o jogador consigo executar movimentos muito irreais como por exemplo, saltar para a esquerda e de repente ainda no ar virar e começar a cair para a direita. É também muito útil para a criação de cut-scenes.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->spawnPoint: O conceito de Spawn Point é interessante. Quando seu personagem morrer, entrar em alguma passagem, túnel, portas, etc, esse conceito é extremamente útil para facilitar a sua vida na hora de tele-portar um personagem para o local de destino. Esta variável nada mais é do que uma coordenada qualquer em seu espaço 3D para onde o personagem pode ser movido.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->floorHitFX: Já criamos uma variável de mesmo nome em nosso primeiro script. Ela faz referência ao clipe de som que usaremos aqui para ser usado como efeito de quando o personagem atinge o chão de maneira brusca. Não se pode esquecer de assinar um Audio Clip da sua lista de Assets. Se você não tiver nenhum áudio á mão, pode baixar alguns de sites frees pela web ou pode apenas ignorar esta questão do tutorial.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->isSneaking: Esta variável se torna verdadeira todas as vezes em que um objeto que faz parte da layer escolhida se sobrepõem sobre a cabeça do personagem em determinada altura que o impeça de se manter de pé. Infelizmente os cálculos usados para fazer o personagem entender que precisa se manter agachado são um tanto fora do foco e fazem parte de outros scripts que detectam colisões e raycasts, por isso pode complicar o entendimento e desviar a atenção, então deixaremos este tópico para um outro tutorial.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->isFalling: Esta variável deve se tornar verdadeira todas as vezes em que o personagem estiver caindo de uma altura exagerada ou saltar de forma descontrolada, indicando que ele sofrerá uma queda dolorosa ao invés de um pouso comum. Esta funcionalidade utiliza os mesmos princípios básicos que isSneaking, mas é apenas uma regra simples dentro do próprio loop Update() que executa um raycast em direção ao solo e se a altura for muita, o personagem sofrerá uma queda ao atingir o solo.<!--[if !supportLists]-->·&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <!--[endif]-->headsUp: Esta variável deve se tornar verdadeira todas as vezes que o raycast implementado por outro script na cabeça do personagem indicar que existe um objeto muito próximo que o impede se manter de pé. Faz parte do sistema que identifica se ele está agachado ou não. Esta variável é usada como um gatilho que força o personagem a se abaixar mesmo contra a vontade do jogador enquanto ele não se afastar do obstáculo que o impede de se manter de pé.6.9 Classes AuxiliaresCom nossas variáveis bem definidas, podemos seguir em frente com a implementação de nossas classes que auxiliarão na programação de toda a movimentação de nosso personagem:?
      1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465      class PlatformerControllerMovement{&nbsp;&nbsp;&nbsp;&nbsp;var walkSpeed = 3.0;&nbsp;&nbsp;&nbsp;&nbsp;var runSpeed = 10.0;&nbsp;&nbsp;&nbsp;&nbsp;var inAirControlAcceleration = 1.0;&nbsp;&nbsp;&nbsp;&nbsp;var gravity = 60.0;&nbsp;&nbsp;&nbsp;&nbsp;var maxFallSpeed = 20.0;&nbsp;&nbsp;&nbsp;&nbsp;var speedSmoothing = 5.0;&nbsp;&nbsp;&nbsp;&nbsp;var rotationSmoothing = 5.0;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var direction = Vector3.zero;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var verticalSpeed = 0.0;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var speed = 0.0;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var isMoving = false;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var collisionFlags : CollisionFlags;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var velocity : Vector3;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var inAirVelocity = Vector3.zero;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var hangTime = 0.0;
&nbsp;&nbsp;&nbsp;&nbsp;var sneakControllerHeight : float = 0.95;&nbsp;&nbsp;&nbsp;&nbsp;var sneakControllerCenter : Vector3 =   Vector3(0,0.5,0);}
class PlatformerControllerJumping{&nbsp;&nbsp;&nbsp;&nbsp;var enabled = true;&nbsp;&nbsp;&nbsp;&nbsp;var height = 1.0;&nbsp;&nbsp;&nbsp;&nbsp;var extraHeight = 4.1;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var repeatTime = 0.05;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var timeout = 0.15;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var jumping = false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var reachedApex = false;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var lastButtonTime = -10.0;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var lastTime = -1.0;
&nbsp;&nbsp;&nbsp;&nbsp;@System.NonSerialized&nbsp;&nbsp;&nbsp;&nbsp;var lastStartHeight = 0.0;}  
Sobre nossas classes:Ao salvar seu script, você pode ver que todas as variáveis expostas das classes aparecem de maneira elegante e organizada no Inspector.Não existem mais tantas dúvidas sobre a funcionalidade das animações, então não há necessidade de informação redundante. O que estas irão fazer é simplesmente pegar as informações que o player insere através de valores seja em um gamepad ou teclado e implementar a interatividade, mandando mensagens nos momentos certos para que as animações sigam a lógica definida pela interatividade proposta. Neste momento em diante a questão de jogabilidade vai se tornando cada vez mais presente e você se ver por horas e horas aprimorando a movimentação e Gameplay de seu personagem. Em uma situação assim com tantas variáveis co-relacionadas é sempre bom utilizar uma classe para tornar o trabalho menos doloroso.Com nossas classes definidas, vamos em frente em trabalhar com o conteúdo oferecido por elas:?
      123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241      function Awake(){&nbsp;&nbsp;&nbsp;&nbsp;movement.direction =   transform.TransformDirection(Vector3.forward);&nbsp;&nbsp;&nbsp;&nbsp;controller =   GetComponent(CharacterController);&nbsp;&nbsp;&nbsp;&nbsp;Spawn();}
function FixedUpdate(){&nbsp;&nbsp;&nbsp;&nbsp;transform.position.z = 0;}
function Update(){&nbsp;&nbsp;&nbsp;&nbsp;if (isDying != true)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Input.GetButtonDown   ("Jump") &amp;&amp; canControl) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jump.lastButtonTime   = Time.time;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UpdateSmoothedMovementDirection();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplyGravity();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplyJumping();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lastPosition =   transform.position;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var currentMovementOffset =   movement.direction * movement.speed + Vector3 (0, movement.verticalSpeed, 0)   + movement.inAirVelocity;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;currentMovementOffset   *= Time.deltaTime;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.collisionFlags   = controller.Move (currentMovementOffset);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.velocity =   (transform.position - lastPosition) / Time.deltaTime;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (movement.direction.sqrMagnitude   &gt; 0.01)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transform.rotation   = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation   (movement.direction), Time.deltaTime * movement.rotationSmoothing);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (controller.isGrounded) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.inAirVelocity   = Vector3.zero;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (jump.jumping) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jump.jumping   = false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage   ("DidLand", SendMessageOptions.DontRequireReceiver);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var jumpMoveDirection =   movement.direction * movement.speed + movement.inAirVelocity;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (jumpMoveDirection.sqrMagnitude   &gt; 0.01)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.direction   = jumpMoveDirection.normalized;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UpdateEffects ();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (isSneaking == true)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (controller.height !=   movement.sneakControllerHeight) {controller.height =   movement.sneakControllerHeight;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (controller.center != movement.sneakControllerCenter)   {controller.center = movement.sneakControllerCenter;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (headsUp == false)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (controller.height != 1.85)   {controller.height = 1.85;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (controller.center !=   Vector3(0,0.98,0)) {controller.center = Vector3(0,0.98,0);}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var hit : RaycastHit;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var floorRect =   transform.TransformDirection(Vector3(0,-1,0));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Physics.Raycast(transform.position,floorRect,hit))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (hit.distance &gt;= 6.5)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isFalling   = true;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (isFalling == true)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Input.GetButton("Jump"))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (jump.enabled == true)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.Stop("Fall");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;animation.CrossFade("Stay   Jumping");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;isFalling   = false;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;}}
function UpdateSmoothedMovementDirection(){ &nbsp;&nbsp;&nbsp;&nbsp;var h = Input.GetAxisRaw ("Horizontal");&nbsp;&nbsp;&nbsp;&nbsp;if (!canControl)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h = 0.0;
&nbsp;&nbsp;&nbsp;&nbsp;movement.isMoving = Mathf.Abs (h) &gt; 0.1;&nbsp;&nbsp;&nbsp;&nbsp;if (movement.isMoving)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.direction =   Vector3 (h, 0, 0);
&nbsp;&nbsp;&nbsp;&nbsp;if (controller.isGrounded)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var curSmooth =   movement.speedSmoothing * Time.deltaTime;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var targetSpeed = Mathf.Min   (Mathf.Abs(h), 1.0);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (isSneaking == false &amp;&amp; headsUp == false)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Input.GetButton ("Action   A") &amp;&amp; canControl)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;targetSpeed   *= movement.runSpeed;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}   &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;targetSpeed   *= movement.walkSpeed;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;targetSpeed   *= movement.walkSpeed;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.speed =   Mathf.Lerp (movement.speed, targetSpeed, curSmooth);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.hangTime =   0.0;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.hangTime +=   Time.deltaTime;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (movement.isMoving)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.inAirVelocity   += Vector3 (Mathf.Sign(h), 0, 0) * Time.deltaTime *   movement.inAirControlAcceleration;&nbsp;&nbsp;&nbsp;&nbsp;}}
function Spawn(){&nbsp;&nbsp;&nbsp;&nbsp;movement.verticalSpeed = 0.0;&nbsp;&nbsp;&nbsp;&nbsp;movement.speed = 0.0;&nbsp;&nbsp;&nbsp;&nbsp;if (respawnPoint != null)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;transform.position =   respawnPoint.position;&nbsp;&nbsp;&nbsp;&nbsp;}}
function ApplyGravity(){&nbsp;&nbsp;&nbsp;&nbsp;var jumpButton = Input.GetButton ("Jump");&nbsp;&nbsp;&nbsp;&nbsp;if (!canControl)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jumpButton = false;
&nbsp;&nbsp;&nbsp;&nbsp;if (jump.jumping &amp;&amp; !jump.reachedApex   &amp;&amp; movement.verticalSpeed &lt;= 0.0) &nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jump.reachedApex =   true;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage   ("DidJumpReachApex", SendMessageOptions.DontRequireReceiver);&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;var extraPowerJump = jump.jumping &amp;&amp;   movement.verticalSpeed &gt; 0.0 &amp;&amp; jumpButton &amp;&amp;   transform.position.y &lt; jump.lastStartHeight + jump.extraHeight &amp;&amp;   !IsTouchingCeiling ();&nbsp;&nbsp;&nbsp;&nbsp;if (extraPowerJump)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;&nbsp;&nbsp;&nbsp;&nbsp;else if (controller.isGrounded)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.verticalSpeed   = -movement.gravity * Time.deltaTime;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.verticalSpeed   -= movement.gravity * Time.deltaTime;
&nbsp;&nbsp;&nbsp;&nbsp;movement.verticalSpeed = Mathf.Max   (movement.verticalSpeed, -movement.maxFallSpeed);}
function ApplyJumping(){&nbsp;&nbsp;&nbsp;&nbsp;if (isSneaking != true &amp;&amp; headsUp != true)&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (jump.lastTime +   jump.repeatTime * 15 &gt; Time.time)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (controller.isGrounded) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (jump.enabled &amp;&amp;   Time.time &lt; jump.lastButtonTime + jump.timeout) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;movement.verticalSpeed   = CalculateJumpVerticalSpeed (jump.height);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SendMessage   ("DidJump", SendMessageOptions.DontRequireReceiver);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;}}
function CalculateJumpVerticalSpeed(targetJumpHeight   : float){&nbsp;&nbsp;&nbsp;&nbsp;return Mathf.Sqrt (2 * targetJumpHeight *   movement.gravity);}
function DidJump(){&nbsp;&nbsp;&nbsp;&nbsp;jump.jumping = true;&nbsp;&nbsp;&nbsp;&nbsp;jump.reachedApex = false;&nbsp;&nbsp;&nbsp;&nbsp;jump.lastTime = Time.time;&nbsp;&nbsp;&nbsp;&nbsp;jump.lastStartHeight = transform.position.y;&nbsp;&nbsp;&nbsp;&nbsp;jump.lastButtonTime = -10;&nbsp;&nbsp;&nbsp;&nbsp;canControl = true;}
function GetSpeed(){&nbsp;&nbsp;&nbsp;&nbsp;return movement.speed;}
function GetVelocity(){&nbsp;&nbsp;&nbsp;&nbsp;return movement.velocity;}
function IsMoving(){&nbsp;&nbsp;&nbsp;&nbsp;return movement.isMoving;}
function IsJumping(){&nbsp;&nbsp;&nbsp;&nbsp;return jump.jumping;}
function IsTouchingCeiling(){&nbsp;&nbsp;&nbsp;&nbsp;return (movement.collisionFlags &amp; CollisionFlags.CollidedAbove)   != 0;}
function GetDirection(){&nbsp;&nbsp;&nbsp;&nbsp;return movement.direction;}
function GetHangTime(){&nbsp;&nbsp;&nbsp;&nbsp;return movement.hangTime;}
function Reset(){&nbsp;&nbsp;&nbsp;&nbsp;gameObject.tag = "Player";}
function SetControllable(controllable   : boolean){&nbsp;&nbsp;&nbsp;&nbsp;canControl = controllable;}  
E assim temos ambos os scripts que controlam tanto as animações quando a jogabilidade básica do personagem como andar, correr, saltar, cair, agachar, se arrastar, etc. O script acima é uma forma de física controlada e por isso, em certos momentos, envolve muita matemática que pode ser muito confusa se você não conhecer ao menos um pouco sobre física. Ler alguns livros sobre o assunto é sempre muito útil.A partir deste ponto, se tudo correu bem, seu personagem deve estar andando, correndo e saltando normalmente.É possível que você tenha talvez alguma dificuldade para executar o tutorial, se for o caso, provavelmente você ainda precisa se ambientar melhor com a interface da Unity e conhecer mais a fundo seus conceitos antes de se arriscar em animar um personagem que nesse caso pode ser uma questão complexa. Se você teve dificuldades em seguir este tutorial por não ser um passo-a-passo, é normal, este tutorial é focado em explicar “conceitos” ao invés de indicar exatamente como algo deve ser feito e por isso há muita coisa não explicada aqui que você precisa pesquisar por si próprio.Bem, minha parte termina aqui, mas a sua está apenas começando, se você estiver mesmo disposto a por em prática os códigos exemplificados aqui, não tente apenas copiar e colar, isso definitivamente não irá funcionar. Estude com atenção, procure realmente entender o que está acontecendo em cada linha e não muito além você se verá desenvolvendo funções ainda mais poderosas e se tornando cada vez mais seguro e experiente para tentar conteúdo cada vez mais avançado.Por exemplo, tente implementar você mesmo as funções que forçam o personagem a se manter agachado e crie objetos no cenário para testar a funcionalidade e ir aos poucos aprimorando sua função. Garanto que você vai se divertir tanto que certa hora você se verá mais jogando seu game do que trabalhando nele! Rsrsrs.Você pode também criar obstáculos que explodam e gerem dano no seu personagem, criar uma ragdoll, etc.Crie um script que mantenha o estado do seu personagem, como por exemplo, vidas, barra de energia, etc.Você pode criar efeitos com partículas e aplicálos ao seu spawnPoint indicando visualmente que o personagem aparece naquele ponto, pode criar também respawnPoints onde o personagem continuará a partir dalí se caso ele morrer, etc.Enfim, divirta-se com a Unity enquanto aprende e ao mesmo tempo produz. Acredito que isto seja o segredo de qualquer coisa que exige dedicação, faça por diversão e não por obrigação. Boa sorte!