Aprendendo a programar jogos em Unity: controlando a movimentação dos personagens

Realizaremos a implementação de códigos para controle de parâmetros de caminhada e rotação dos nossos personagens.

em 20/10/2024
Seja bem-vindo(a) ao GameDev: Aprendendo a programar jogos em Unity de hoje! Após realizarmos no encontro anterior diversos ajustes de parâmetros físicos e de colisão para o objeto que representa o paciente-modelo de nosso consultório, daremos início à implementação de códigos que permitirão ao jogador controlar a movimentação dos modelos humanoides em nosso cenário, por meio de determinadas teclas de seu teclado.

Caso esta seja a primeira vez que você acessa a série, sinta-se especialmente convidado a juntar-se a nós em um processo de aprendizado repleto de conteúdos interessantes sobre desenvolvimento de games.

Estamos desenvolvendo atualmente o projeto Consultório do Dr. Tratanildo, que trata da elaboração de um divertido jogo ambientado em um consultório tridimensional, cujo processo de elaboração está nos proporcionando a aquisição de diferentes habilidades que envolvem o mais variado conjunto de atividades: elaboração de cenários e gameplay, posicionamento de elementos, configuração e codificação de itens e regras do jogo.


A partir do primeiro texto da série, nós teremos a oportunidade de pôr a mão na massa em mais de um projeto, fazendo com que, aos poucos, estejamos aptos a desenvolver os mais diferentes tipos de jogos e, quem sabe, possamos tirar do papel aquela aventura em específico que sempre sonhamos em ver “de verdade” sendo jogada nas telinhas.

Venha conosco nesta caminhada rumo a novos conhecimentos!

De volta aos scripts

Para quem nos acompanha desde os primórdios da série, talvez esteja reparando que estamos demorando um pouco mais para chegar à etapa de codificação do game em comparação aos demais jogos criados até o momento. Isso é normal, visto que o nível de complexidade para desenvolver uma aventura tridimensional geralmente é maior do que a implementação direta de um jogo em duas dimensões.

Agora que já temos uma boa composição de elementos em nosso cenário e, também, já delineamos um bom fluxo de animação para a caminhada de nossos personagens pelo consultório, que tal começarmos a codificar um pouco, permitindo o controle do personagem pelo cenário ao pressionar determinadas teclas de seu teclado?

Para iniciarmos esta nova etapa, vamos abrir o projeto para edição. Para isso, abra o Unity Hub e clique duas vezes sobre o item referente ao projeto Consultório do Dr. Tratanildo. Na interface inicial do Unity, na aba Project, abra a pasta Assets, Scenes e, por fim, clique duas vezes no ícone da cena ConsultorioScene

Vamos criar uma pasta nova para armazenarmos os scripts controladores que iremos elaborar. Para isso, na aba Project, abra a pasta Assets, clique com o botão direito do mouse em uma área vazia da janela e, no menu suspenso, selecione a opção Create e, por fim, Folder.

Dê o nome “Scripts” (sem as aspas) à nova pasta, conforme indicado a seguir, e abra-a após sua criação, clicando duas vezes sobre seu ícone.

Ainda na aba Project, em uma área vazia da pasta Scripts, clique novamente com o botão direito do mouse e, no menu suspenso, desta vez iremos selecionar a opção Create e, por fim, C# Script.

Conceda o nome “ControllerMov_Tank” (sem as aspas) ao novo script criado. Clique duas vezes sobre seu ícone para iniciarmos sua edição no Visual Studio.

Controles estilo tank

Conforme vimos em um dos encontros iniciais preparatórios para a elaboração do projeto Consultório do Dr. Tratanildo, existem diferentes estilos de controle de personagens para ambientes tridimensionais. Uma das técnicas mais utilizadas no início da popularização dos jogos 3D para consoles domésticos foi a adoção de controles em estilo tank, como os utilizados nos primeiros jogos da franquia Resident Evil:

Embora outros estilos sejam mais populares hoje em dia, os tank controls são mais fáceis de serem implementados, portanto inicialmente iremos utilizá-los como forma de nos introduzirmos aos conceitos fundamentais de movimentação de personagens em cenários 3D.

A primeira parte de nosso novo script, que iremos inserir logo após a declaração da classe ControllerMov_Tank (depois da abertura da chave ‘{‘), é o trecho de código descrito a seguir:

    public Animator personagemAnim;    
    float velocidadeCaminhada = 0;

A variável global personagemAnim servirá para indicarmos ao script qual controlador de animação receberá influências de seus parâmetros e códigos. Concretamente, em nosso primeiro exemplo, será o Animator Controller que está atrelado ao GameObject do paciente. Já a variável velocidadeCaminhada servirá para que possamos controlar a velocidade a ser passada ao parâmetro Passo_caminhada do controlador.

A segunda parte do código, a ser inserida dentro das chaves da função void Start(), é a linha descrita a seguir:

        personagemAnim.SetFloat("Passo_caminhada", 0);

Iremos conceder o valor 0 ao parameter Passo_caminhada do controlador de animação ao iniciarmos a execução do script, evitando movimentos não esperados ao se iniciar o jogo.

Para finalizar a “primeira rodada” de codificações de hoje, iremos inserir dentro das chaves da função void Update() o seguinte trecho de código:

        // Controle do avanço para frente
        if (Input.GetKey(KeyCode.UpArrow))
            velocidadeCaminhada = Mathf.Min(velocidadeCaminhada + Time.deltaTime, 1.0f);
        else velocidadeCaminhada = 0.0f;

        personagemAnim.SetFloat("Passo_caminhada", velocidadeCaminhada);

Este código será responsável por indicar dinamicamente ao Animator Controller do personagem um novo valor ao parâmetro Passo_caminhada, baseado na seguinte regra:
  • Se o usuário estiver no momento com a tecla “seta para cima” (UpArrow) de seu teclado pressionada, o valor de Passo_caminhada subirá gradativamente até atingir o valor 1;
  • Caso o usuário não pressione mais a tecla “seta para cima”, o valor de Passo_caminhada será revertido imediatamente para 0.
Dessa forma, o personagem irá acelerar seu passo até o limite determinado (no caso, o valor 1) e irá parar seu deslocamento no momento em que o jogador assim desejar, ou seja, ao deixar de pressionar a tecla “seta para cima”.

Salve o script e minimize o Visual Studio. Volte ao editor do Unity para que possamos atrelar o novo script ao objeto do personagem que representa o paciente, a fim de testar o funcionamento do que criamos.

Na aba Hierarchy, selecione o GameObject paciente_base, subordinado a Pacientes. Na aba Inspector, clique sobre o botão Add Component e adicione um componente do tipo Controller Mov_Tank, conforme indicação a seguir:

Altere o valor do parâmetro Personagem Anim do novo componente inserido para paciente_base, seja clicando e arrastando o item do referido GameObject da aba Hierarchy em direção à caixa de seleção, seja por meio da seleção do item na lista de objetos da caixa de seleção.

Vamos simular a execução do game, indo à aba Game e clicando sobre o ícone do botão Play. Lembre-se de testar a movimentação do personagem, pressionando a tecla “seta para cima” após iniciada a simulação:

Ao término dos testes, interrompa a simulação, clicando novamente sobre o ícone do botão Play e retornando à aba Scene

Movimentação lateral

Para finalizarmos as intervenções propostas para nosso encontro de hoje, iremos implementar a movimentação lateral do personagem. Como inicialmente estaremos utilizando controles em estilo tank, são poucas as alterações que faremos ao script

Volte ao Visual Studio para editarmos ControllerMov_Tank. Logo após a última linha inserida dentro das chaves da função void Update(), vamos acrescentar o seguinte trecho de código:

        //Controle da movimentação lateral (tank)

        Vector3 rotacaoPersonagem = transform.eulerAngles;

        if (Input.GetKey(KeyCode.RightArrow))
            rotacaoPersonagem.y += (Time.deltaTime * 120);
        else if (Input.GetKey(KeyCode.LeftArrow))
            rotacaoPersonagem.y -= (Time.deltaTime * 120);

        transform.eulerAngles = rotacaoPersonagem;

Conforme vimos em um dos encontros que tivemos para a construção do platformer 2D Motorista da Pesada, o Unity realiza os cálculos de rotação de objetos por meio de uma extensão do conjunto de números complexos conhecida como Quaternions, que são bem mais contraintuitivos do que os tradicionais graus e ângulos que aprendemos na escola, durante as aulas de trigonometria.


Por isso, em vez de alterarmos diretamente os valores de transform.rotation para obtermos modificações na rotação de um objeto via código, normalmente alteramos os valores de transform.eulerAngles; parâmetro este representado por um Vector3 que representa os três eixos espaciais de rotação X, Y e Z já convertidos em graus.

O código inserido é responsável por alterar a rotação do eixo Y do objeto, aumentando seu valor ao se pressionar a tecla “seta para a direita” (RightArrow) e reduzindo-o, caso o jogador pressione a tecla “seta para a esquerda” (LeftArrow).

Os valores de acréscimo estão sendo multiplicados por 120 para dar dinamicidade a essa alteração. Como uma rotação completa é composta por 360 graus, levaremos no máximo 3 segundos para dar uma volta completa ao redor do eixo Y.

Feita essa inserção, salve o script e feche o Visual Studio. Retorne ao Unity para simularmos a execução do game via aba Game. Experimente controlar o personagem pressionando as teclas configuradas:

Interrompa a simulação da execução, clicando novamente sobre o ícone do botão Play. Não se esqueça de salvar a cena (menu File, opção Save) e o projeto (menu File, opção Save Project) antes de fechar o editor.

Próximos passos

Finalmente iniciamos uma pequena parte da codificação de nosso game, ao darmos liberdade de movimentação ao nosso personagem por meio da elaboração de um script controlador. Parabéns por chegar até esta etapa!

Em nossos próximos encontros prosseguiremos codificando alguns comportamentos para nossos personagens e realizaremos correções e acréscimos ao ambiente tridimensional do consultório.

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

Revisão: Ives Boitano

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