Aprendendo a programar jogos em Unity: iniciando a elaboração da segunda fase

Vamos dar início ao desenvolvimento da próxima fase e aprender mais sobre compressão de imagens no Unity.

em 10/02/2024
Seja bem-vindo(a) ao GameDev: Aprendendo a programar jogos em Unity de hoje! Prosseguindo em nossa caminhada rumo à criação de nosso primeiro platformer 2D, começaremos a desenvolver a tão esperada segunda fase de nosso game. Utilizando o conteúdo criado para a primeira fase como ponto de partida, logo teremos em nosso projeto mais um estágio pronto de nossa aventura.


Caso esta seja a primeira vez que você acessa nossa série, sinta-se à vontade para vir conosco nesta jornada de aprendizado. Aprenderemos, por meio de exemplos práticos, muitos conteúdos sobre o processo de desenvolvimento de jogos utilizando a ferramenta Unity: a partir do primeiro tópico, você irá aprender a configurar a ferramenta em seu computador, quais são os processos de programação envolvidos, como construir as cenas, objetos e fases de um jogo, dentre muitos outros tópicos importantes para dar vida aos games que sempre sonhou em tirar do papel.

No momento, estamos elaborando Motorista da Pesada, um platformer cujo objetivo proposto ao gamer é a coleta, no menor tempo possível, de todas as caixas de presente distribuídas pelos cenários. Para isso, o jogador guiará um simpático carrinho e transitará entre fases repletas de itens coletáveis e, também, de perigosas bombas, que, se forem tocadas, podem representar o fim de sua jornada.

No tópico anterior de nossa jornada, concluímos a elaboração da primeira fase do game, ao distribuirmos caixas de presentes animadas pelo cenário e introduzirmos os efeitos sonoros a serem executados em caso de vitória ou derrota na fase. Venha conosco e vamos juntos nesta jornada rumo a novos conhecimentos!

Tudo novo, mas tudo igual

Desde o início da concepção de Motorista da Pesada, realizamos inúmeras inclusões e alterações até obtermos uma primeira fase bonita e funcional; então, nada mais justo do que, no desenvolvimento do segundo estágio, podermos reaproveitar parte desse trabalho, em vez de iniciarmos a construção de uma nova fase “do zero”.

Sendo assim, o primeiro passo que realizaremos será a criação de uma cópia do arquivo que armazena as informações da primeira fase, efetivamente “clonando-a”, pronta para edição já como estrutura-base para o segundo desafio dessa jornada.

Abra o Unity Hub e clique duas vezes sobre o item referente ao projeto Motorista da Pesada. Na interface inicial do Unity, na aba Project, abra a pasta Assets e, em seguida, Scenes. Clique com o botão direito sobre o ícone da cena Fase01 e selecione a opção Show in Explorer.

Uma janela do Explorador de Arquivos do Windows será aberta, já com a pasta Scripts aberta. Clique com o botão direito sobre o item Fase01 (não o arquivo com a extensão final .meta) e realize a operação de “copiar e colar” na mesma pasta. Renomeie o novo arquivo gerado para “Fase02”, conforme exemplo a seguir:

Minimize a janela do Explorador de Arquivos e volte ao editor do Unity. Note que, agora, surgiu um novo ícone dentro da pasta Scene, na aba Project: trata-se do arquivo que irá armazenar os dados referentes à Fase02. Clique duas vezes sobre o ícone para abrirmos a nova fase no editor.

À primeira vista, ao se abrir Fase02, não iremos notar diferenças significativas em relação à Fase01

De fato, ao copiarmos o arquivo que armazena as informações da primeira fase do game, também são copiados todos os GameObjects, seus componentes e atributos, o que irá poupar (e muito) nosso trabalho, já que diversos elementos que estão presentes em Fase01 serão mantidos, como as estruturas de placar, de menus e o objeto referente ao  personagem principal.

Vamos começar, então, a dar à Fase02 uma personalidade própria, trocando a temática visual de céu azul e tranquilidade para uma ambientação no interior de uma floresta.

No menu Hierarchy, selecione os GameObjects Parte1 e Parte2, subordinados a Fundo (que, por sua vez, encontra-se subordinado a Cenario). Na aba Inspector, altere o parâmetro Sprite de seu componente Sprite Renderer para a imagem de nome “fundoFloresta”, conforme exemplo a seguir:

Note que, apesar de termos agora um novo fundo em nossa cena, surgiu um espaço vazio entre os dois elementos que compõem nosso fundo. Se simularmos a execução do game, isso torna-se bem nítido:

Esse espaço vazio que surgiu tem relação com a diferença de tamanho entre o arquivo de imagem utilizado para compor o fundo de Fase01 e o que será aproveitado neste momento.

Compressão de imagens

A princípio, realizando ajustes nos parâmetros do componente Mov Fundo de Parte1 e Parte2, conseguiremos resolver este problema; entretanto, antes de fazê-los, vamos observar alguns aspectos importantes que envolvem a dimensão dos arquivos de imagem que estamos utilizando e que, se levados em consideração, podem diminuir o tamanho de nosso game, facilitando sua posterior compilação e publicação.

Para isso, na aba Project, abra as pastas Assets, Multimidia e, por fim, Imagens. Note que temos três arquivos de imagem que irão compor o fundo das três fases de nosso game: “fundoCeuAzul.jpg”, “fundoCidade.jpg” e “fundoFloresta.jpg”.

Ao clicar sobre cada uma das imagens, uma área com o nome do elemento selecionado será exibida no canto inferior da aba Inspector, contendo uma pré-visualização da imagem e informações sobre as dimensões e o tamanho em disco que cada imagem irá utilizar ao se concluir a elaboração do projeto:

Note que, apesar de todas terem dimensões diferentes, não são tão grandes as diferenças entre elas nesse quesito. Porém, em relação ao tamanho em disco, fundoFloresta se destaca por exigir bem mais espaço do que as demais: são 8,0 MB, em contraste com apenas 1,1 MB de fundoCeuAzul e 0,8 MB de fundoCidade.

Isso se deve à funcionalidade interna de compressão de imagens do Unity, que exige algumas condições sobre o tamanho do arquivo antes de realizar de fato a diminuição no tamanho exigido em disco. Selecionando o arquivo “fundoFloresta.jpg”, no final da lista de componentes da aba Inspector pode se notar a presença de um aviso, em destaque na imagem a seguir:


Esse aviso nos informa que, para a realização da compressão, o arquivo deverá apresentar valores de altura e largura divisíveis por quatro. Vamos então redimensionar nossa imagem, para que a compressão possa funcionar adequadamente, diminuindo significativamente o tamanho em disco a ser ocupado pela imagem.

Neste exemplo, iremos utilizar o programa Paint, que já vem instalado em conjunto com o Windows, para redimensionarmos a imagem, mas, se preferir, você poderá utilizar o editor de imagens de sua escolha.

No editor do Unity, na aba Project, clique com o botão direito sobre o ícone que representa o arquivo “fundoFloresta.jpg” e selecione a opção Show in Explorer.

Na janela que for exibida, clique com o botão direito sobre o arquivo referente à imagem e, no menu suspenso, selecione a opção Abrir com e, em seguida, Paint, conforme exemplificado na imagem a seguir:

Com a imagem aberta no Paint, selecione a opção de redimensionamento, em destaque na cor laranja a seguir:

Na pequena janela que for apresentada, selecione a opção Pixels, desative a opção “manter proporções” (ícone do cadeado, destacado em verde na imagem a seguir) e modifique os valores Horizontal para 5248 e Vertical para 3484. Por fim, clique no botão OK.


Note que a imagem se modificou bem pouco, pois não houve uma alteração brusca de suas dimensões. Clique no ícone do disquete (Salvar, em destaque na ilustração) e feche o aplicativo.

Volte ao editor do Unity e clique sobre o ícone de “fundoFloresta.jpg”. Veja que, agora, o espaço em disco que será utilizado para armazenar será bem menor do que o exigido anteriormente: apenas 1,3 MB. Porém, note que as dimensões informadas pelo Unity em relação à imagem são diferentes das que editamos no aplicativo Paint: 2048 pixels na horizontal, 1360 pixels na vertical:


As dimensões apresentadas pelo Unity referem-se ao tamanho que a imagem terá após a realização da compressão; no caso, por padrão, o Unity considera que iremos armazenar a imagem com, no máximo, 2048 pixels de largura e de altura.


Podemos alterar esse valor máximo modificando o parâmetro Max Size presente no final da listagem da aba Inspector. Modifique o valor para 1024 e clique no botão Apply:


Note que, dessa forma, conseguiremos reduzir ainda mais o espaço em disco a ser utilizado pela imagem após sua compressão: apenas 340,0 KB, o equivalente a 0,34 MB. 

Podemos realizar a mesma operação com quais imagens quisermos, porém é importante ressaltar que imagens que tiverem suas dimensões muito reduzidas tendem a aparecer na tela do jogo com menor qualidade visual.

Para padronizarmos os parâmetros de compressão das imagens utilizadas nas fases, repita a operação de modificação do parâmetro Max Size (1024) para os arquivos “fundoCeuAzul.jpg” e “fundoCidade.jpg”. Note, agora, que o tamanho em disco a ser ocupado por cada arquivo ficou bem menor:

Outro ponto interessante a se levar em consideração é que o Unity permite a configuração individualizada dos parâmetros de compressão para cada plataforma em que forem disponibilizados os jogos. Esses parâmetros são alcançáveis pelos ícones destacados a seguir:


Dessa forma, pode-se criar configurações específicas para atender plataformas específicas, que suportem melhor diferentes métodos de compressão ou formatos. Esse mesmo recurso é válido também para outros tipos de mídia pelo Unity, como por exemplo na conversão de sons, pois determinados sistemas podem suportar ou não determinados tipos de arquivos sonoros, requerendo medidas específicas para seu bom funcionamento.

Fechando o espaço

Agora que já solucionamos a questão do tamanho a ser ocupado pela imagem que irá compor o fundo de nossa segunda fase, vamos resolver o problema do "vão", presente entre Parte1 e Parte2.

Na aba Hierarchy, selecione o GameObject Parte2 e modifique o valor X do parâmetro Position de seu componente Transform para 52.4, fazendo com que, ao menos inicialmente, fechemos o espaço entre Parte1 e Parte2.

Note que, mesmo que pouco perceptível, existe uma descontinuidade do desenho entre a extremidade direita de Parte1 e a extremidade esquerda de Parte2.

Para solucionarmos isso, ainda com Parte2 selecionado, ative o parâmetro Flip X do componente Sprite Renderer do objeto. Dessa forma, a imagem será desenhada na tela de forma espelhada, bem mais bonita do que com a falha de continuidade identificada.

Por fim, na aba Hierarchy, selecione Parte1 e Parte2 para alterarmos parâmetros do componente Mov Fundo de ambos. Modifique os parâmetros Limite Min para -52.4 e Limite Max para 52.4, refletindo o novo posicionamento inicial de Parte2 em nossa segunda fase.

Experimente simular a execução do jogo, indo à aba Game e pressionando o botão Play. Ao término da simulação (pressionando novamente Play), retorne à aba Scene.

Consertando uma pequena falha

Talvez você tenha notado que, em determinados momentos da execução do jogo, mesmo configurando os parâmetros de Mov Fundo e posicionando corretamente os dois GameObjects que compõem o fundo de nossa fase, uma pequena fenda pode aparecer entre ambos. Essa fenda faz parecer que há um pequeno "descompasso" na transição entre os dois objetos na tela:

Isso deve-se a uma pequena falha no cálculo do novo posicionamento dos objetos, após avançarem, na cena, os valores limitadores mínimo e máximo.

Vamos corrigir um trecho de código presente no script MovFundo para solucionarmos esse problema que estava acometendo, inclusive, o deslocamento de fundo de nossa primeira fase.

Na aba Project, abra a pasta Assets, Scripts e, por fim, clique duas vezes sobre o ícone do script MovFundo para realizarmos sua edição no Visual Studio.

No trecho de código em que realizamos o deslocamento da imagem para a outra extremidade da tela, após a passagem pelos limites laterais, vamos alterar dois trechos de código em destaque na próxima imagem. Os códigos a serem alterados são os descritos a seguir:
  • Na condição (transform.position.x < limiteMin)
    • De: (velocidade * direcao * Time.deltaTime * 60)
    • Para: (transform.position.x - limiteMin)
  • Na condição  (transform.position.x > limiteMax)
    • De: (velocidade * direcao * Time.deltaTime * 60)
    • Para: (transform.position.x - limiteMax)
Altere apenas os campos indicados na imagem anterior, e não todas as instâncias em que (velocidade * direcao * Time.deltaTime * 60) aparece no script.

Com essa correção, após a passagem da imagem por um dos limites determinados (limiteMin ou limiteMax) ser detectada, a imagem será deslocada à outra extremidade (limiteMax ou limiteMin, respectivamente), considerando, também, a pequena distância que já havia sido ultrapassada. No diagrama a seguir, essa pequena distância está destacada em amarelo:

Salve o script e minimize o Visual Studio. Volte ao editor do Unity e experimente a simulação da execução do game; a falha já não acontecerá mais.

Não se esqueça de, após interromper a simulação, salvar a cena (menu File, Save) e o projeto (menu File, Save Project) antes de fechar o Unity.

Próximos passos

Estamos começando a dar forma ao segundo estágio de nosso platformer. Embora já tenhamos modificado o fundo, ainda temos muitas alterações a realizar; por exemplo, o placar e itens visuais precisam de ajustes para obterem um contraste adequado:

Também pudemos aprender hoje sobre alguns fundamentos do sistema de compressão de imagens do Unity que podem nos ajudar a elaborar games utilizando de forma mais otimizada o espaço de armazenamento do dispositivo do jogador.

Em nosso próximo encontro continuaremos a editar Fase02, modificando aspectos relativos às questões visuais da fase, posicionamento de plataformas, itens, bombas e outros elementos relevantes.

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.