GameDev

Aprendendo a programar jogos em Unity: iniciando a construção da terceira fase do game

Iniciaremos agora a elaboração da última fase de nossa aventura rodoviária, com nova ambientação gráfica e novos perigos.

em 08/03/2024
Seja bem-vindo(a) ao GameDev: Aprendendo a programar jogos em Unity de hoje! Prosseguindo na jornada de desenvolvimento de nosso primeiro platformer, iremos agora iniciar os procedimentos para a criação do terceiro (e último) estágio do game.


Caso esta seja a primeira vez que você acessa nossa série, sinta-se à vontade para juntar-se a nós nesta grande trilha de aprendizado. Por meio da realização de diversas atividades práticas, iremos conhecer mais sobre o processo de criação de jogos utilizando a ferramenta Unity.

A partir do primeiro tópico, você poderá aprender a criar os mais diversos tipos de games: abordamos desde a instalação e configuração da ferramenta em seu computador até a codificação de scripts, a composição de cenas e o posicionamento dos elementos pertencentes às fases de um jogo.

No momento, estamos desenvolvendo o platformer bidimensional Motorista da Pesada. Trata-se de um game cujo objetivo proposto ao jogador é realizar a coleta, no menor tempo possível, de todas as caixas de presente espalhadas em cada cenário das fases, utilizando-se para isso de um simpático carrinho, guiando-o pelos infinitos caminhos de cada estágio.

Ao mesmo tempo que o gamer tem de ficar atento para não esquecer de coletar nenhum presente, também deverá se atentar aos perigos da aventura: a contagem regressiva incessante do cronômetro e a presença de bombas estrategicamente posicionadas nas fases, prontas para “dar cabo” dessa curiosa epopeia sobre quatro rodas.


No tópico anterior de nossa jornada, finalizamos a construção do segundo estágio do game, realizando também alguns ajustes bem-vindos a todo o conjunto de fases construídas até o momento no projeto.
Agora, estamos com o caminho livre para iniciarmos a elaboração da derradeira fase de Motorista da Pesada. Venha conosco e vamos juntos nesta jornada rumo a novos conhecimentos!

Iniciando a construção

Assim como fizemos anteriormente ao iniciarmos a construção da segunda fase, o primeiro passo que iremos realizar na elaboração da terceira fase será copiar o arquivo que armazena informações sobre uma cena já construída (no caso, Fase02) para que possamos utilizá-lo como base na montagem do terceiro estágio do game.

Sendo assim, vamos abrir o Unity Hub e clicar duas vezes sobre o item referente ao projeto Motorista da Pesada. Na aba Project, abra a pasta Assets e, por fim, Scenes. Clique com o botão direito sobre o ícone da cena Fase02 e selecione a opção Show in Explorer.

Uma janela do Explorador de Arquivos será aberta. Clique com o botão direito sobre o ícone de “Fase02” (o arquivo sem o final “.meta”), copie-o e cole na mesma pasta uma cópia do arquivo. Renomeie a cópia criada para “Fase03”, sem as aspas, conforme exemplo ilustrado a seguir.

Volte ao editor do Unity e note que, agora, a aba Project apresenta quatro ícones, referentes às cenas de nosso projeto (Fase01, Fase02, a recém-criada Fase03 e MenuInicial). Clique duas vezes sobre Fase03 para iniciarmos sua composição.

Como copiamos o arquivo que armazena as informações de Fase02 para criarmos Fase03, em princípio, a composição dos itens da cena é a mesma da fase anterior, como era de se esperar. 

Agora, daremos início ao processo de “urbanização” da fase, trocando o fundo e alguns elementos de apoio da cena.

Uma cidade começa a surgir

Na aba Hierarchy, selecione os GameObjects Parte1 e Parte2, subordinados a Fundo (que, por sua vez, encontra-se subordinado a Cenario). Na aba Inspector, troque o valor do parâmetro Sprite de seus componentes do tipo Sprite Renderer para a imagem de nome “fundoCidade”.

Pelas diferenças de dimensão entre o arquivo de imagem utilizado na composição da fase anterior e o novo arquivo referenciado em Fase03, é nítido que teremos que realizar alguns ajustes, pois, além de a nova imagem ser praticamente quadrada (e não retangular, como as que compunham as fases anteriores), um enorme espaço se abriu entre Parte1 e Parte2, conforme podemos perceber a seguir:

Vamos corrigir, então, a proporção que os sprites devem apresentar na tela, para compor de forma adequada o cenário. Na aba Project, abra as pastas Assets, Multimidia e, por fim, Imagens. Selecione o ícone referente ao arquivo de imagem “fundoCidade.jpg”. Na aba Inspector, altere o valor do parâmetro Pixels Per Unit para 27 e clique em Apply. Note que, com a correção da proporção de pixels da imagem pelos valores unitários de medida do Unity, agora a imagem cobre verticalmente toda a extensão da tela:

Como os sprites de fundo apresentam dimensões horizontais menores do que as imagens utilizadas nas fases anteriores, para que o efeito de deslocamento contínuo proporcionado pelo script Mov Fundo ocorra sem deixar “espaços vazios” na transição entre imagens, vamos aumentar para quatro o número de partes que irão compor o fundo do cenário.

Na aba Hierarchy, novamente iremos selecionar os GameObjects Parte1 e Parte2. Clique com o botão direito sobre os itens e selecione a opção Duplicate, conforme indicado a seguir:


Renomeie os objetos recém-criados conforme indicações a seguir:
  • De “Parte1 (1)” para “Parte3”; e
  • De “Parte2 (1)” para “Parte4”.
Selecione os quatro GameObjects que representam as partes do fundo e, na aba Inspector, altere os valores dos parâmetros Position Y de seus respectivos componentes Transform para -4. Iremos realizar essa alteração para posicionar adequadamente o reflexo da cidade no espelho d’água abaixo dos objetos que representam o chão.

Ainda em relação ao posicionamento dos objetos, altere individualmente os valores dos parâmetros Position X dos componentes Transform para os indicados a seguir:
  • Parte1: X = -20;
  • Parte2: X = 28;
  • Parte3: X = 76; e
  • Parte4: X = 124.
Note que, agora, todos os objetos que compõem o fundo da fase estão sequencialmente posicionados de forma correta. Confira, também, se Parte2 e Parte4 estão com o parâmetro Flip X ativado em seus respectivos componentes de tipo Sprite Renderer, para que não sejam apresentadas “quebras” nas transições entre imagens.

Selecione novamente os quatro GameObjects e altere os parâmetros Limite Min e Limite Max de seus componentes Mov Fundo para -55 e 137, refletindo adequadamente a nova composição dos “extremos” do cenário.


Que tal conferirmos a simulação da execução do game, para vermos em ação o novo fundo da fase que estamos construindo? Para isso, vá até a aba Game e pressione o botão Play.

Interrompa a simulação, clicando novamente sobre o botão Play e retornando à aba Scene.

Modificando o chão

Embora a alteração do fundo da fase já comece a dar uma nova identidade ao novo estágio, ainda temos muito o que alterar para, de fato, parecer que estamos dirigindo em uma moderna cidade.

O próximo passo contemplará a alteração da composição do chão do cenário. Curiosamente, não temos no projeto nenhum asset disponível que represente diretamente asfalto ou outro tipo de piso urbano. Para preencher essa lacuna, iremos realizar uma adaptação bem interessante, aproveitando sprites não utilizados do conjunto de imagens referentes aos presentes coletáveis.

Selecione os GameObjects Chao01 e Chao02, subordinados a Itens. Na aba Inspector, altere os parâmetros Sprite de seus respectivos componentes Sprite Renderer para a imagem de nome “presentes_6”, conforme exemplo a seguir:

Em princípio, temos um chão composto de inúmeros quadradinhos amarelos, representando vagamente uma rua de paralelepípedos. Como os componentes de tipo Sprite Renderer dos objetos apresentam o valor Tiled em seus parâmetros Draw Mode, o Unity desenhará repetidas vezes o sprite informado até preencher as dimensões do GameObject, sem “esticar” a imagem, de forma semelhante ao que foi realizado na composição visual do chão nas fases anteriores.

Vamos agora ajustar as dimensões das imagens que representam o chão, para que eles apresentem proporções mais adequadas, correspondentes ao tamanho vertical do sprite utilizado na composição.
Selecione Chao01 e Chao02 e, na aba Inspector, altere os parâmetros Size Width e Size Height de seus componentes Sprite Renderer para 15 e 0.5, respectivamente.

Como realizamos alterações nas dimensões de tamanho do elemento Sprite Renderer, teremos que ajustar, também, as dimensões dos colisores, visto que estão bem maiores do que a imagem apresentada na tela, como podemos perceber na imagem a seguir, em relação às linhas verdes em volta dos elementos ajustados.

Modifique os parâmetros Size X e Size Y dos componentes Box Collider 2D de Chao01 e Chao02 para 15 e 0.5, respectivamente. Veja como as dimensões dos colisores agora apresentam correspondência com o tamanho das imagens na tela:

Perigos na pista

Muito provavelmente você percebeu que não ajustamos apenas as dimensões verticais dos elementos visuais de Chao01 e Chao02. Talvez até tenha pensado se tratar de um engano, pois até o momento o chão de todas as fases não apresentava descontinuidades aparentes. Pois bem, não se trata de um engano.

Por meio do ajuste dos parâmetros horizontais de Chao01 e Chao02, iremos implementar um dos mais clássicos desafios de um platformer 2D tradicional: vãos verticais sem fundo.

Quem nunca errou o cálculo de um pulo em Super Mario Bros., encaminhando o famoso encanador italiano a uma queda fatal, que atire a primeira pedra.


Em Motorista da Pesada, seremos um pouco mais “cruéis” do que a Nintendo: ao cair em um poço sem fundo em nosso platformer, o gamer perderá todas as vidas que lhe restam no jogo!

Para implementarmos essa nova mecânica de jogo, teremos que informar ao game, de alguma forma, que ocorreu uma queda e lhe instruir a decretar o fim da partida. Vamos começar criando um novo objeto, que será responsável por detectar a queda do personagem principal em um buraco. Na aba Hierarchy, clique com o botão direito sobre o objeto Cenario e selecione a opção Create Empty.


Dê ao novo GameObject o nome “BuracoFim01”, sem as aspas. Selecione-o e, na aba Inspector, acrescente um novo componente do tipo Box Collider 2D. Seus parâmetros Size X e Size Y deverão receber os valores 20 e 0.3, respectivamente. Deixe selecionado também o parâmetro Is Trigger do referido componente.

Vamos posicioná-lo bem abaixo do nível do chão, para que a detecção da queda ocorra após, de fato, o personagem cair nos buracos sem fundo da fase. Modifique o valor do parâmetro Position Y de seu componente Transform para -7.

Para que haja a efetiva detecção da queda, basicamente necessitamos que, ao ocorrer um encontro entre o personagem principal e o colisor de BuracoFim01, sejam zeradas as vidas do jogador, ativando a sequência de fim de partida. Podemos criar um novo script para acionar essa sequência, mas, como já temos implementado um script que faz praticamente a mesma coisa, porém retirando apenas uma unidade de vida por “encontro” (script Itens para elementos classificados como “Bombinha”), vamos reaproveitá-lo.

Ainda com BuracoFim01 selecionado, na aba Inspector acrescente um componente do tipo Itens. Deixe ativa a seleção para a variável Bombinha, conforme exemplo a seguir:

Conforme você deve se lembrar, ao se encostar em um elemento classificado como “bombinha”, é subtraída apenas uma vida do total que o gamer ainda tem à disposição e o GameObject é destruído. Como faremos, então, para subtrair todas as vidas de uma só vez no momento em que o carrinho do jogador cair no abismo?

Detecção correta

Como a quantidade máxima de vidas disponível em qualquer momento de nossas partidas é sempre três unidades, vamos criar duas cópias de BuracoFim01 e posicioná-las estrategicamente abaixo do original. É uma solução simples, que irá atender ao que precisamos no momento.

Na aba Hierarchy, clique com o botão direito sobre BuracoFim01 e selecione a opção Duplicate. Repita a operação mais uma vez. Renomeie os dois objetos novos para “BuracoFim02” e “BuracoFim03”.


Ajuste o valor do parâmetro Position Y do componente Transform de BuracoFim02 para -7.3. Repita a mudança para BuracoFim03, concedendo o valor -7.6 para o parâmetro do GameObject. Observe, pela marcação em verde dos elementos Box Collider 2D na tela, que os GameObjects estão alinhados um após o outro no sentido vertical:

Agora vamos experimentar a execução do jogo, indo à aba Game e pressionando o botão Play. Veja que o comportamento esperado ocorre de forma consistente:

Ao término da simulação de execução, salve a cena (menu File, Save) e o projeto (menu File, Save Project) antes de fechar o Unity.

Próximos passos

Começamos a desenvolver a última etapa de nosso projeto, agora contando com interessantes novidades, tais como a presença de perigosos vãos entre os elementos que compõem o chão, o que poderá aumentar significativamente o nível de desafio para os jogadores de Motorista da Pesada.

No próximo encontro, prosseguiremos construindo a terceira fase do game, personalizando elementos do cenário e realizando ajustes na quantidade e no posicionamento de presentes e bombinhas pelos caminhos. 

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.