Aprendendo a programar jogos em Unity: inclinando o labirinto “ao vivo” com as teclas direcionais

Iniciaremos a codificação de scripts que permitirão o manejo da inclinação do labirinto pelos jogadores.

em 08/12/2024
Seja bem-vindo(a) ao GameDev: Aprendendo a programar jogos em Unity de hoje! Após realizarmos interessantes alterações no projeto em nosso encontro anterior, permitindo ao jogador visualizar tanto o labirinto quanto o cenário ao mesmo tempo, iremos conceder em nosso game a possibilidade de inclinar o labirinto de forma direta, por meio do pressionamento de determinadas teclas.

Se esta for a primeira vez que você acessa nossa série, não se acanhe e junte-se a nós em uma divertida jornada de novos aprendizados no fascinante mundo do desenvolvimento de games.

Por meio da elaboração de projetos práticos, você terá a oportunidade de aprender mais sobre como a ferramenta Unity pode nos ajudar a criar jogos de diversos gêneros e estilos de gameplay. No momento, estamos elaborando o projeto Consultório do Dr. Tratanildo, um game ambientado em um consultório médico tridimensional, cujo desenvolvimento está nos permitindo aprender diferentes conceitos envolvendo as peculiaridades da criação de um jogo em 3D, tais como o posicionamento de objetos e da câmera, movimentação de personagens, entre outros.


Mesmo que você não tenha tido experiências prévias no mundo da programação de jogos, permita-se aprender! A partir do primeiro texto da série, são abordados desde os tópicos considerados mais básicos, como a instalação e configuração da ferramenta em nossos computadores, até o desenvolvimento de fato das fases, regras do jogo, itens, desafios e os demais elementos que fazem parte da composição de um game.

Venha conosco para, juntos, seguirmos nesta caminhada rumo a novos conhecimentos!

Classe estática

Até o momento, elaboramos interessantes elementos que farão parte de nosso labirinto, tais como as pílulas miraculosas e os agentes de doenças. Porém, ainda não configuramos o projeto para que, a partir do pressionamento de determinadas teclas, a inclinação do labirinto seja realizada dentro do contexto do jogo, e não por meio de alterações realizadas via editor, como fizemos até o momento para experimentar as mecânicas desenvolvidas:

Iremos iniciar a implementação dessa funcionalidade por meio da criação e configuração de novos scripts controladores. Para tal, vamos abrir nosso projeto para edição: no Unity Hub, clique duas vezes sobre o item referente ao projeto Consultório do Dr. Tratanildo. Na interface inicial do editor, na aba Project, abra a pasta Assets, Scenes e, por fim, clique duas vezes no ícone da cena ConsultorioScene.

Na aba Project, abra a pasta Assets e, em seguida, Scripts. Clique com o botão direito sobre um espaço vazio da pasta e, no menu suspenso, selecione a opção Create e, por fim, C# Script, conforme exemplo:

Conceda o nome “Geral”, sem as aspas, ao novo script criado. Esse script servirá como um controlador geral de variáveis importantes do game como um todo, tais como o modo corrente do jogo (se estamos controlando a inclinação do labirinto ou a movimentação do doutor pelo cenário), o tempo restante da aventura, entre outras.

Clique duas vezes em seu ícone para abrir o script para edição no Visual Studio. Selecione todo o conteúdo textual do novo script e troque-o pelo código a seguir:

public static class Geral
{
    public static string ModoDeJogoCorrente;
}

Com o novo código inserido, transformamos Geral em uma classe estática, pronta para disponibilizar suas variáveis internas a todos os scripts do projeto sem a necessidade de ser atrelada a um GameObject em específico. A primeira variável codificada de forma estática é ModoDeJogoCorrente, que indica se, em determinado momento, estaremos controlando o labirinto ou o doutor pelo cenário, dependendo de seu valor.

Inclinando o labirinto

Salve o script e minimize o Visual Studio. De volta ao editor do Unity, ainda com a pasta Scripts em evidência na aba Project, crie um novo script de nome “ControllerMov_Labirinto”, sem as aspas. Será este script o responsável por identificar os comandos do jogador e permitir a inclinação do labirinto, fazendo com que as pílulas possam percorrer os caminhos internos dos corpos dos pacientes.

Clique duas vezes sobre o ícone de ControllerMov_Labirinto para editarmos seu conteúdo no Visual Studio. Inicialmente, vamos declarar algumas variáveis, inserindo o código a seguir antes da declaração da função void Start():

    public float taxaInclinacao;
    public Vector3 inclinacoesMaximas, inclinacoesMinimas;
    internal Vector3 rotacaoCalculada;

As variáveis declaradas serão responsáveis pelos seguintes papeis em nosso game:
  • taxaInclinacao: variável pública do tipo float, responsável por armazenar a taxa de inclinação que será aplicada ao labirinto ao pressionarmos um botão do teclado. Posteriormente, também será utilizada para a inclinação da cama do leito, por meio da ação da máquina elaborada pelo doutor Tratanildo Doencita;
  • inclinacoesMaximas e inclinacoesMinimas: essas duas variáveis públicas serão utilizadas para indicarmos, via editor do Unity, quais serão os limites positivos e negativos de inclinação horizontal e vertical que devem ser respeitados durante o manejo dos parâmetros de rotação do labirinto;
  • rotacaoCalculada: essa variável interna será utilizada para armazenarmos o resultado dos cálculos que serão efetuados, tendo seu valor aproveitado pelo Unity para determinar qual a rotação do labirinto a ser aplicada ao componente Transform de seu GameObject.
Agora, insira nas chaves da função void Start() o seguinte trecho de código:

        rotacaoCalculada = Vector3.zero;
        transform.localEulerAngles = rotacaoCalculada;

O código que inserimos irá iniciar o labirinto sempre com valores de rotação “neutros”, representados pelo Vector3 com todos os valores de seus atributos (X, Y e Z) iguais a zero.

Finalmente, iremos inserir no script o bloco de código a seguir dentro das chaves da função void Update():

        // Inclinações
        if (Geral.ModoDeJogoCorrente == "Labirinto")
        {
            Vector3 alteracoesInclinacao = new Vector3();

            // Para "frente" e para "trás"
            if (Input.GetKey(KeyCode.UpArrow))
                alteracoesInclinacao.x += taxaInclinacao * Time.deltaTime;
            if (Input.GetKey(KeyCode.DownArrow))
                alteracoesInclinacao.x -= taxaInclinacao * Time.deltaTime;

            // Para os lados
            if (Input.GetKey(KeyCode.LeftArrow))
                alteracoesInclinacao.z += taxaInclinacao * Time.deltaTime;
            if (Input.GetKey(KeyCode.RightArrow))
                alteracoesInclinacao.z -= taxaInclinacao * Time.deltaTime;

            // Calcular a posição prévia
            rotacaoCalculada += alteracoesInclinacao;

            // Enquadrar os valores entre o mínimo e o máximo estipulados
            rotacaoCalculada = Vector3.Min(Vector3.Max(rotacaoCalculada, inclinacoesMinimas),inclinacoesMaximas);

            // Passar a rotação para o GameObject
            transform.localEulerAngles = rotacaoCalculada;

Em resumo, o código inserido realizará as seguintes operações, desde que o jogo esteja em “modo labirinto” (representado pelo valor da variável Geral.ModoDeJogoCorrente):
  • Serão concedidos valores positivos ou negativos aos parâmetros X e Z de alteracoesInclinacao, dependendo do botão pressionado no teclado e do valor da variável taxaInclinacao. O pressionar das setas para cima e para baixo influenciará o valor do parâmetro X, e o das setas para esquerda e para direita influenciará o valor do parâmetro Z;
  • Ao conteúdo da variável rotacaoCalculada, serão acrescidos os valores do Vector3 alteracoesInclinacao;
  • Antes de transportar o valor de rotação calculado e armazenado em rotacaoCalculada para transform.localEulerAngles (a rotação local do objeto em questão), são efetuadas verificações dos valores dos atributos de rotacaoCalculada para garantir que a inclinação não ultrapasse os limites estabelecidos em inclinacoesMinimas e inclinacoesMaximas, por meio das funções matemáticas Mathf.Max() e Mathf.Min() do Unity;
  • Por fim, com tudo devidamente verificado e confirmado, o atributo transform.localEulerAngles é finalmente atualizado.
Salve o script e volte ao editor Unity para continuarmos a configurar os elementos pertencentes ao labirinto, a fim de que o código recém-implementado funcione de fato em nosso game.

Na aba Hierarchy, selecione o GameObject Labirinto. Na aba Inspector, adicione um componente do tipo Controller Mov_Labirinto. Conceda os valores a seguir a seus respectivos atributos:
  • Taxa Inclinacao: 10;
  • Inclinacoes Maximas: X = 15, Y = 0, Z = 15;
  • Inclinacoes Minimas: X = -15, Y = 0, Z = -15.
Por fim, para podermos testar o funcionamento da inclinação do labirinto, volte a abrir o script Geral e conceda o valor “Labirinto” (com aspas, dessa vez!) à variável estática ModoDeJogoCorrente, conforme exemplificado pela imagem a seguir:

Salve o script, volte ao Unity e experimente simular a execução do game, indo à aba Game e pressionando o ícone do botão Play. Pressione as setas do teclado e veja que, mesmo acionando continuamente as teclas, a inclinação respeita os limites que estipulamos:

Concluídos os testes, interrompa a simulação, pressionando novamente o 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

Mais uma funcionalidade importante de nosso game foi implementada com sucesso: a inclinação do labirinto por ação do jogador, que permitirá, posteriormente, realizarmos os tratamentos de saúde tão alardeados pelo doutor Tratanildo Doencita em seu consultório.

Em nossos próximos encontros, continuaremos a implementar funcionalidades essenciais de nosso game, envolvendo a interação entre labirinto, leito hospitalar e consultório médico.

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

Revisão: Davi Sousa
Siga o Blast nas Redes Sociais

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. Você pode compartilhar este conteúdo creditando o autor e veículo original (BY-SA 3.0).