Aprendendo a programar jogos em Unity: transições em menus e carregamento de cenas

Vamos concluir a criação do menu de nosso platformer 2D e aprender sobre cenas e ações atreladas a buttons.

em 14/10/2023
Seja bem-vindo(a) ao GameDev: Aprendendo a programar jogos em Unity de hoje! Dando prosseguimento ao processo de desenvolvimento de um novo platformer 2D, iremos concluir a criação do menu principal de nosso game, tarefa que iniciamos em nosso último tópico.


Caso seja a primeira vez que acessa esta série, fique à vontade para juntar-se a nós. A partir do primeiro tópico da jornada você poderá aprender “do zero” a criar um game utilizando Unity, desde o processo de instalação e configuração da ferramenta até o desenvolvimento e criação do produto final em si.

No momento estamos no processo de desenvolvimento do segundo jogo da nossa série e, em paralelo, aprendendo muito sobre diversos aspectos técnicos da ferramenta Unity. Venha conosco e vamos juntos nesta caminhada rumo a novos conhecimentos!

Textos e botões

Retomando o processo de criação de nosso menu inicial, no Unity Hub abra o projeto do game Motorista da Pesada e, na interface inicial do Unity, na aba Project abra a pasta Assets, Scenes e, por fim, clique duas vezes no ícone da cena MenuInicial para voltarmos a trabalhar nela.

Ao término do nosso último tópico, finalizamos a elaboração gráfica do conjunto de GameObjects TelaInicial, mantendo o item TelaSobre desativado temporariamente, conforme mostrado na imagem a seguir:

Iremos agora elaborar os itens pertencentes ao grupo de GameObjects subordinados a TelaSobre. Para isso, na aba Hierarchy, clique em TelaInicial e, na aba Inspector, vamos desativá-lo, deixando a caixa de seleção desmarcada conforme ilustração abaixo.

Faça o mesmo, mas de forma “inversa”, para o GameObject TelaSobre, ativando-o:

Na aba Hierarchy, selecione o objeto Titulo (subordinado a TelaSobre). Em Inspector, para o componente do tipo Text, no campo de texto digite “Sobre o jogo” (sem as aspas) e preencha o restante dos parâmetros conforme exemplo a seguir:

Agora selecione o objeto Conteudo. Em Inspector, para o componente do tipo Text, preencha o campo de texto com a sugestão de texto indicada a seguir, preenchendo o restante dos parâmetros da mesma forma que o indicado na próxima imagem.

"Motorista da Pesada" é um jogo desenvolvido para fins didáticos, como atividade prática no processo de aprendizado de programação de jogos.

Imagens: OpenGameArt.org, Freepik.com
Fontes: Google Fontes / Sons: Filmmusic.io

Todos os direitos reservados aos autores.
Mais informações, acesse https://github.com/GameBlast/Unity_02_MotoristaDaPesada

Para finalizar a composição gráfica dos elementos subordinados a TelaSobre, clique no GameObject Opcao3. No componente Image da aba Inspector, troque a cor do botão para a sugerida pela imagem a seguir, alterando os parâmetros R, G, B e A para os valores indicados.

Em relação ao GameObject subordinado Text e seu respectivo componente Text, no campo de texto preencha com “Voltar” (sem as aspas) e os parâmetros conforme ilustração a seguir:

Veja como ficou bacana a composição gráfica de nossa seção de créditos. Lembrando que sempre é importante citarmos os autores das obras que utilizamos, por isso foi importante indicar no corpo do texto do objeto Conteudo as fontes primárias e indicar mais informações no website do nosso projeto, pois lá encontram-se os dados referentes às autorias detalhadamente.

Agora iremos programar o comportamento dos botões, pois, apesar de terem ficado bonitos, se você simular a execução do game neste exato instante (visitando a aba Game e clicando no botão Play), perceberá que, ao clicar no botão, nada ocorrerá.

Caso tenha simulado a execução, não se esqueça de pressionar novamente o botão Play para encerrá-la e podermos trabalhar os botões.

Comportamento dos botões

A partir de agora iremos indicar aos botões do menu quais os comportamentos que deverão apresentar ao serem clicados. Basicamente o que queremos é que, por meio do clique nos botões, as seguintes ações ocorram:
  • Botão “Voltar” da tela “Sobre o jogo”: ao ser clicado, deve-se desativar a exibição de TelaSobre e ativar a exibição de TelaInicial;
  • Botão “Sobre o jogo” da tela “Bem-vindo ao jogo”: ao ser clicado, deve-se desativar a exibição de TelaInicial e ativar a exibição de TelaSobre; e
  • Botão “Iniciar partida” da tela “Bem-vindo ao jogo”: ao ser clicado, deve-se carregar a cena do projeto que contém a primeira fase do game.
Como vimos no desenvolvimento de nosso primeiro projeto, normalmente utilizamos scripts e códigos para controlar o que acontece nas mais diversas situações de um game, mas nem sempre isso é necessário.

Já que estamos com o GameObject TelaSobre ativo em nossa tela, vamos começar a trabalhar pelo comportamento do botão que contém o texto “Voltar”. Clique sobre o GameObject Opcao3. Na aba Inspector, componente Button, clique por duas vezes sobre o ícone com o sinal de “mais” (+) indicado na imagem a seguir:

Note que, acima do símbolo com o sinal de “mais”, duas entradas foram disponibilizadas abaixo da inscrição On Click (). Essa é uma forma oferecida pelo Unity para a realização de determinadas ações e alterações de parâmetros sem necessariamente precisar criar um script para tal, apenas a partir da detecção de um evento (no caso, o clique sobre um botão) e indicação do que deve ocorrer ou ser alterado.

Para a primeira entrada, abaixo de Runtime Only, clique sobre o campo e selecione TelaInicial, conforme exemplo a seguir:


Já do lado direito de Runtime Only, selecione GameObject e, em seguida, SetActive (bool). Deixe marcada a caixa de seleção, conforme imagem:

Repita os passos realizados na primeira entrada para a segunda, mas informando no campo abaixo de Runtime Only o item TelaSobre e deixando a caixa de seleção desmarcada:


O que acabamos de fazer é indicar ao Unity que, ao se clicar sobre o botão presente no GameObject Opcao3, duas ações deverão ser realizadas: alterar o parâmetro Active do GameObject TelaInicial para “true” (representado pela caixa de seleção marcada) e o do GameObject TelaSobre para “false”, de fato cumprindo com o que planejamos para o botão em questão.

Iremos fazer o mesmo com os outros dois botões que estão presentes em TelaInicial. Para isso, na aba Hierarchy, selecione TelaSobre e desative o objeto na aba Inspector; após, selecione TelaInicial e ative o objeto na aba Inspector.

Clique sobre o GameObject Opcao2, pois iremos editar o comportamento de seu componente Button via aba Inspector. Assim como fizemos com o Opcao3, clique por duas vezes sobre o ícone com o sinal de “mais” (+) indicado a seguir.

A primeira entrada deverá ser preenchida com o GameObject TelaInicial, cujo parâmetro GameObject.SetActive será alterado para “false” (caixa de seleção desmarcada). Já a segunda entrada deverá ser preenchida com o GameObject TelaSobre, cujo parâmetro GameObject.SetActive será alterado para “true” (caixa de seleção marcada).


Clique sobre a aba Game e pressione Play para experimentar o comportamento dos botões. Note que agora há uma transição entre a tela “Bem-vindo ao jogo” e “Sobre o jogo” ao se clicar nos respectivos botões.

Pressione novamente o botão Play para parar a simulação e volte à aba Scene para programarmos o último botão que nos resta.

Carregando uma cena

Para programarmos o botão “Iniciar partida”, precisaremos codificar um pequeno script e associá-lo ao comportamento do componente Button. Para isso, na aba Project abra a pasta Assets, Scripts, clique com o botão direito do mouse sobre alguma área vazia da pasta em questão e selecione o item Create, C# Script. O nome de nosso script será CarregarCena, conforme representação a seguir:

Clique duas vezes sobre o ícone do script para que ele seja aberto pelo Visual Studio. Após a abertura, acrescente a seguinte linha após as entradas que começam com a palavra using:

    using UnityEngine.SceneManagement;

Essa linha é necessária pois iremos chamar uma função de gerenciamento de cenas dentro de nosso código.

Mais abaixo na mesma tela, substitua as funções padrão void Start() e void Update() pela função descrita a seguir:

    public void Carregar(string nomeDaCena)
    {
        SceneManager.LoadScene(nomeDaCena);
    }

A função Carregar (string) será responsável por, dada uma cena cujo nome seja repassado à variável nomeDaCena, finalizar a cena corrente e carregá-la.

Existem outras formas de se carregar cenas, como por exemplo utilizando a função SceneManager.LoadSceneAsync(string nome), mas iremos vê-las posteriormente.

Salve o script no Visual Studio, minimize-o e vamos voltar ao Unity. Selecione o GameObject Opcao1, no final da aba Inspector clique sobre Add Component e acrescente um componente do tipo Carregar Cena, conforme imagem a seguir:

Observe que agora temos nosso novo script atrelado ao objeto, mas temos que, de alguma forma, “chamá-lo” para que faça o que precisamos que seja feito, ou seja, carregar uma cena. Para isso, ainda na aba Inspector, no componente Button clique uma vez sobre o ícone com o sinal de “mais” (+).

Abaixo de Runtime Only, clique sobre o campo e selecione Opcao1. Ao lado de Runtime Only, selecione CarregarCena e, por fim, Carregar (string).

A cena que iremos carregar ao clicarmos no botão tem o nome de “Fase01” (sem as aspas). Preencha o texto no campo indicado na imagem abaixo:


Já que chegamos até aqui, que tal testarmos o funcionamento do botão? Clique sobre a aba Game, pressione Play e experimente clicá-lo.

Pois é, nada aconteceu… mas note que, na extremidade inferior da tela (indicada pela seta), é informado que um erro ocorreu ao se tentar abrir a cena em questão. Esse erro é relacionado ao fato de que é necessário indicar ao Unity quais cenas irão compor as builds de um projeto.

No desenvolvimento de grandes projetos, por vezes algumas cenas são criadas pelos desenvolvedores especificamente para ser exibida em determinada plataforma, formato de tela ou mesmo para fins de testes. Para não tornar os arquivos executáveis dos jogos muito pesados, o Unity não inclui todas as cenas automaticamente, apenas aquelas indicadas pelo programador. Por isso, iremos agora indicar que a cena de nome “Fase01” faz parte de nossos planos.

Pressione novamente o botão Play para parar a simulação e retorne à visualização da aba Scene. Salve a cena corrente clicando no menu File, opção Save. Na aba Project, abra a pasta Assets, Scenes e clique duas vezes sobre o ícone da cena Fase01.

Com a cena aberta, abra o menu File e clique em Build Settings.


Na janelinha que for exibida, clique sobre o botão Add Open Scenes. Além da cena MenuInicial, agora a cena Fase01 também estará listada. Certifique-se de que ambas estão marcadas, como na indicação em verde na imagem a seguir. Feche a janelinha em questão clicando no ícone "X" no canto superior direito.


Na aba Project, ainda com a pasta Scenes aberta, clique duas vezes sobre o ícone da cena MenuInicial. Agora sim teste a execução e veja a “mágica” acontecer.

Finalizando o menu

Para finalizarmos de vez a confecção de nosso menu, clique com o botão direito do mouse sobre algum espaço vazio da aba Hierarchy e, no menu suspenso apresentado, selecione Audio, Audio Source. Dê o nome de AudioAmbienteMenu ao objeto criado.


Clique sobre o GameObject para selecioná-lo. Na aba Inspector, altere os parâmetros Play On Awake e Loop do componente Audio Source para “true” (caixas de seleção marcadas) e em AudioClip escolha a canção de nome “musicaMenu”, conforme imagem a seguir. Ajuste o parâmetro Volume ao seu gosto.

Ao testar novamente a execução da cena, você poderá ouvir uma agradável música enquanto navega pelos botões e opções do menu, evidenciando o poder das multimídias.

Finalize os testes de execução, volte à aba Scene e salve a cena (menu File, opção Save) e o projeto (menu File, opção Save Project).

Próximos passos

Agora que finalizamos de fato a criação do menu de nosso game, em nossa próxima etapa iremos começar a concepção gráfica e posicional dos elementos da primeira fase do platformer 2D Motorista da Pesada. As decisões que tomaremos para definir o layout dos objetos e elementos impactarão no gameplay de nosso jogo, inclusive também posteriormente nas outras fases que serão criadas.

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.