Alura > Cursos de Programação > Cursos de Jogos > Conteúdos de Jogos > Primeiras aulas do curso Unity: criando menus, coletáveis e batalha final em um jogo 2D

Unity: criando menus, coletáveis e batalha final em um jogo 2D

Adicionando menus no jogo - Apresentação

Boas-vindas a este curso! Eu sou o Willian Carvalho, instrutor do curso de jogos da FIAP. Se você é uma pessoa apaixonada por jogos, quer saber como desenvolver um jogo interessante, e busca aprofundar ainda mais seus conhecimentos em Unity, este é o curso perfeito para você.

Audiodescrição: Willian se descreve como um homem branco, de cabelo cacheado preto e curto, barba preta média, bigode longo curvado também preto, e olhos castanho-escuros. Ele veste uma camisa preta com o texto "Game XP" em azul-claro e o logotipo da FIAP em rosa, e está sentado em uma cadeira preta no estúdio da Alura, com uma parede clara ao fundo iluminada em gradiente verde e azul, e uma estante preta à esquerda do instrutor com vários objetos geek e pontos de iluminação amarela.

O que vamos aprender?

Neste curso, vamos dar continuidade ao jogo A Vingança de Blaid e criar várias coisas novas nele.

Por exemplo: iremos construir uma interface de menu totalmente nova para podermos jogar e alterar as opções de volume do jogo conforme desejado. Na tela de jogo, aprenderemos a inserir efeitos de ataque nos inimigos utilizando sistema de partículas.

Também aprenderemos a criar coletáveis, e a mostrar esses coletáveis e as vidas restantes em uma interface interessante para a pessoa jogadora. Ao coletar todas as chaves, a porta abre.

Ao final, vamos implementar a batalha com o chefão, do qual precisamos correr para evitar danos. Além disso, iremos aprender a criar um GameLoop para o jogo, ou seja, quando o personagem morre, ele volta ao início para tentarmos novamente, e ao ganhar, vamos para a tela de créditos.

Entenderemos como aplicar mais boas práticas do que as utilizadas anteriormente, e também criaremos a tela de créditos com todas as pessoas que nos ajudaram a desenvolver o jogo.

Quais são os pré-requisitos?

Para melhor aproveitamento, recomendamos fazer o primeiro curso da formação (Unity: Criando um jogo metroidvania 2D), onde damos início ao desenvolvimento do jogo A Vingança de Blaid.

Conclusão

Além dos vídeos explicando o desenvolvimento de cada mecânica nova, também deixamos conteúdos extra para você estudar e se aprofundar nos conhecimentos que aplicaremos no jogo.

Caso tenha alguma dúvida, recomendamos acessar o fórum para conversar conosco. Se você quiser interagir com pessoas que estão realizando o mesmo curso, acesse o Discord da Alura, onde temos uma comunidade bastante ativa e interessante.

Vamos estudar? Te aguardamos no próximo vídeo!

Adicionando menus no jogo - Criando menu no jogo

Já temos o jogo em funcionamento, com todas as mecânicas de nível prontas. Porém, ainda não temos uma interface para o jogo. Precisamos criar essa interface para deixar o jogo com uma aparência mais profissional e também mais intuitiva para as pessoas jogadoras.

Criando o menu do jogo

Recapitulando, temos o jogo A Vingança de Blaid, onde conseguimos atacar nos personagens inimigos e também receber dano deles. O que realmente falta é o menu.

No momento, o instrutor está com o som do jogo desativado, o que pode ser feito no botão de alto falante no canto superior direito. Caso queira, você pode ativar ou desativar.

Criando a cena Menu

Para criar o menu, primeiro precisamos acessar a pasta de cenas ("Scenes"), no painel Project do canto inferior esquerdo, e criar uma nova cena.

Para isso, selecionamos a pasta "Scenes", clicamos com o botão direito sobre ela, e vamos até "Create > Scene". Uma vez criada uma nova cena, será solicitado um nome, que definiremos como Menu. A partir disso, criaremos a primeira interface com a qual a pessoa usuária irá interagir.

Construindo a cena Menu

Agora vamos sair da cena de jogo (Game) e acessar a cena Menu; basta clicar duas vezes sobre a pasta "Scenes" no painel Project e depois uma vez no item Menu.

No momento, temos a tela de jogo completamente zerada, pois acabamos de criar uma cena nova. A cena de antes era outra com itens diferentes. Agora teremos uma cena totalmente completa para o nosso jogo. Com essa cena vazia, podemos dar início à criação do menu efetivamente.

Para criar a interface de usuário, além de clicar e arrastar os objetos que tínhamos anteriormente, precisaremos realizar algumas outras ações, pois a interface funciona de forma diferente.

Criando um painel

Primeiramente, vamos clicar com o botão direito sobre o painel Hierarchy do canto superior esquerdo, e selecionar a opção "UI > Panel". Quando criamos um Panel, aparece na hierarquia um Canvas contendo um Panel, e depois um EventSystem. O Canvas é onde vamos colocar todos os itens de UI que a cena possuir.

Hierarchy

Observação: todas as outras cenas terão um Canvas.

No Panel que acabamos de criar, criaremos o menu. Se observarmos a cena (Scene) no momento, identificamos uma tela grande no canto superior direito.

Ao selecionar o Panel no painel Hierarchy, voltar para a cena, e teclar "F", notaremos que o Panel está muito maior do que a câmera.

Isso acontece porque a Unity, para facilitar o nosso desenvolvimento, decidiu colocar tudo que for desenvolvido em UI em uma tela maior, ampliando a visualização do que é UI e do que é jogo.

Na aba de Game, podemos visualizar o painel ocupando todo o espaço. Portanto, quando formos desenvolver um Canvas, isto é, uma UI, geralmente, usamos o layout de Game.

Dito isso, vamos clicar sobre a aba Game na parte superior, arrastá-la e posicionar à direita, logo à esquerda da aba "Inspector". Dessa forma, conseguimos enxergar a cena do Canvas e também o resultado de como ele fica na tela Game. Usaremos esse layout da Unity para desenvolver a interface.

Ajustando o tamanho do painel

Dando continuidade, vamos ajustar o tamanho do painel de Scene. Para realizar esse ajuste, vamos até a aba "Inspetor", onde temos um componente chamado "Rect Transform", em vez de "Transform".

Trata-se de um componente específico para itens que são UI, e ele tem algumas opções a mais disponíveis. No entanto, o que nos interessa é a escala (Scale).

A escala sempre será a mesma (X: 1, Y: 1, Z: 1); o que vamos mudar serão as posições de "Right", "Left", "Top" e "Bottom". Porém, não vamos alterar pela aba "Inspector", mas sim em Scene.

Para isso, vamos selecionar a ferramenta "Rect Tool" no menu flutuante na lateral esquerda de Scene. Não devemos usar a escala, pois podemos perder definição ao aumentar ou diminuir a escala de itens de UI. Após selecionar a "Rect Tool", podemos ajustar para o tamanho desejado.

Se quisermos que o painel mantenha a proporcionalidade, em vez simplesmente arrastar a partir dos vértices do painel, podemos manter a tecla "Shift" pressionada antes de selecionar esses vértices e depois arrastá-los. Dessa forma, ele continua proporcional.

Trabalhando com cores

Outra coisa importante para observar na aba "Inspector" à direita é a seção de imagem ("Image"), onde temos o campo "Color". Ao clicar nele, podemos escolher várias cores, mas o importante para nós é o Alpha, na parte inferior da janela "Color".

No momento, ele está transparente, marcando o valor 105. Vamos deixá-lo em 100%, movendo a barra para a direita até o valor máximo de 255. Inicialmente, temos uma pré-configuração que a Unity faz para os painéis, mas vamos alterar para 100% no nosso caso.

Trabalhando com imagens

As imagens também são muito interessantes. Em "Source Image", ela está definida como "Background". Novamente, vamos alterar para deixar a imagem conforme desejamos.

Para isso, clicaremos no botão à direita de onde temos "Background" (ícone semelhante a um alvo), no campo "Source Image". Ao clicar nele, surge a opção de selecionar imagens (Select Sprite).

Como há muitas imagens em "Assets", podemos utilizar a barra de pesquisa para buscar por "Panel", filtrar os resultados, e depois escolhermos o painel que mais se identifica conosco.

Nesse momento, precisamos importar os assets de interface, para depois realizarmos as alterações. Basta trazer os assets para o projeto e salvar em "Assets > _external".

Finalizada a importação dos assets, armazenados na pasta "_external" como padrão, podemos analisar os itens adicionados através do painel Project no canto inferior esquerdo da Unity.

Observação: o asset kenney_ui-pack está com esse nome porque kenney é a pessoa que criou o pacote de interface e recomendamos manter os créditos dela, para dar valor à pessoa Dev responsável.

Podemos retornar ao Panel no painel Hierarchy e selecionar o botão à direita do campo "Source Image" novamente. Agora, se buscarmos por "Panel" na barra de pesquisa, aparecem cinco painéis diferentes de cores distintas, representados por quadrados. São eles:

Você pode selecionar o painel que preferir, mas no nosso caso, selecionaremos o grey_panel. Agora, já temos as características principais para criar o nosso painel e dar um título para ele.

Criando o título do painel

Começaremos criando um novo Panel dentro do primeiro Panel, para representar a área do título. Esse painel será representado por um retângulo azul na parte superior do painel principal.

Hierarchy

Utilizando o TextMeshPro

Agora precisamos escrever o título efetivamente. Para isso, vamos clicar sobre o último painel criado com o botão direito e ir até "UI > Text - TextMeshPro".

No nosso caso, deixamos o TextMeshPro pré-importado, mas para você irá aparecer uma aba de importação, onde basta selecionar a opção "Import TMP Essentials".

Caso queira visualizar alguns exemplos, clique no botão da parte inferior para importar os exemplos e os extras. Para este projeto, estamos apenas com os essenciais.

Hierarchy

Feito isso, conseguimos acessar o componente "TextMeshPro - Text (UI)" na aba "Inspector" à direita. Lembre-se de deixar selecionado o texto (Text (TMP)) na hierarquia à esquerda.

Na seção do TextMeshPro, há algumas opções disponíveis. Primeiramente, vamos escrever em "Text Input" o título do jogo, que é "A Vingança de Blaid". Inicialmente, ele fica pequeno no painel. Para ajustar esse tamanho, podemos selecionar a "Rect Tool" novamente e esticar a partir das bordas.

Note que aparece uma opção de alterar a largura do texto. Não recomendamos usá-la, pois pode atrapalhar na hora de deixar a interface mais responsiva. Deixaremos um Para saber mais após este vídeo para explicar melhor como deixar a interface responsiva, mas faremos algumas alterações pontuais no momento e explicaremos ao longo do processo.

Alterando o tamanho do título

Ajustaremos o tamanho do texto usando a "Rect Tool", de modo que ele ocupe toda a área do painel azul. Deixaremos apenas uma borda ao redor para evitar qualquer problema.

Ainda com o Text (TMP) selecionado, vamos à aba "Inspector" para realizar algumas alterações. Primeiro, mudaremos o tamanho da fonte ("Font Size") para 52.

Alterando o alinhamento do título

Abaixo, encontramos as opções de alinhamento ("Alignment"), que no momento está definido como canto superior esquerdo. Entretanto, queremos alinhar o texto no centro, então podemos alterar os alinhamentos para "Center" e "Middle", para ficar no centro e no meio.

Alterando a fonte do título

A última alteração que vamos fazer será na fonte ("Font Asset"). Em kenney_ui-pack, há uma pasta de fontes ("Font") contendo os seguintes itens:

No momento, ainda não conseguimos utilizar as fontes disponíveis. Para utilizar as fontes dentro da Unity com o TextMeshPro, precisamos criar um asset de fonte, isto é, um Font Asset.

Para fazer isso, vamos selecionar a fonte desejada na pasta do projeto (nesse caso, kenvector_future), clicar com o botão direito sobre ela, e ir até "Create > TextMeshPro > Font Asset". Uma alternativa é utilizar o atalho "Shift + Ctrl + F12".

Criado o nosso primeiro Font Asset, que vem com o nome kenvector_future SDF, vamos utilizar o atalho "Shift + Ctrl + F12" para criar outro Font Asset, mas com a fonte kenvector_future_thin selecionada. Ao final, teremos os seguintes itens na pasta "Font":

Vamos verificar como fica o resultado de cada tipo de fonte? Podemos clicar sobre a primeira (kenvector_future SDF) e arrastar para o texto. Em seguida, faremos o mesmo para kenvector_future_thin SDF. No caso do instrutor, ele preferiu a primeira opção.

Conclusão

Já conseguimos implementar o texto e configurá-lo da forma como gostaríamos. Dessa forma, temos uma configuração inicial do menu. Agora falta implementar os botões para podermos ir de fato para o jogo ou sair dele. Faremos isso no próximo vídeo!

Adicionando menus no jogo - Implementando os botões do menu

Agora que temos uma configuração inicial do menu, vamos começar a implementação dos botões, pois sem eles, não conseguimos ir para lugar nenhum no jogo.

Implementando os botões do menu

Renomeando os itens de menu

No nosso menu, podemos verificar que já existem algumas coisas feitas, mas observe que, no painel Hierarchy do canto superior esquerdo, temos um Canvas contendo um Panel, que por sua vez, contém outro Panel e, por fim, um Text (TMP). É difícil se identificar dessa forma.

Sendo assim, vamos renomear os itens da hierarquia antes de dar continuidade. Com o Canvas selecionado, basta pressionar "F2" e renomear para MenuUI.

O primeiro Panel, onde ficarão guardados todos os itens de menu, será chamado de MenuContainer. Já o segundo Panel se chamará TitlePanel.

Por fim, o Text (TMP) será alterado para TitleText.

Hierarchy

A partir de agora, qualquer item criado, receberá um nome próprio para o objeto.

Criando os botões

Para criar o botão, vamos selecionar o MenuContainer no painel Hierarchy, clicar sobre ele com o botão direito, e ir até "UI > Button - TextMeshPro". Com isso, o botão estará pronto.

Hierarchy

Feito isso, podemos aumentar o tamanho do botão conforme desejado. No nosso caso, não manteremos a proporcionalidade, porque cada botão tem seu próprio tamanho.

Dentro do item Button, temos um texto (Text (TMP)), que é o texto do botão. Com esse item selecionado, podemos ir até a aba "Inspector" e inserir um nome no campo "Text Input". Chamaremos esse primeiro botão de "Start", que será responsável por iniciar o jogo.

Também podemos alterar a imagem no campo "Source Image". À direita de UISprite, opção selecionada nesse campo no momento, basta clicar no ícone de alvo, como fizemos com o título.

Na janela "Select Sprite" que será aberta, podemos buscar por "Button" para acessar uma grande variedade de opções. Você pode escolher a que preferir. No nosso caso, vamos fazer a configuração de três botões: um de iniciar jogo; outro de opções; e um último de saída.

Verificando o resultado dos botões

Ao final, teremos três botões de cores diferentes dispostos verticalmente: o primeiro "JOGAR" no topo com fundo verde-claro; o segundo "OPÇÕES" no centro com fundo amarelo; e o terceiro "SAIR" abaixo com fundo vermelho. Para criá-los, duplicamos o primeiro botão, ajustamos os tamanhos, e realizamos alterações nas cores, nas imagens, e nos textos de cada botão.

Hierarchy

Ajustamos os textos para o estilo desejado e com a fonte correta, definimos outras cores, como a do botão "SAIR" (ExitButton) para ficar mais chamativo e ter uma aparência de jogo, e, além disso, mudamos a cor do texto no painel de título. Achamos preto uma cor bacana para esse componente. Por fim, aumentamos um pouco o painel em si, para os botões não ficarem muito próximos.

Lembre-se! Os botões, o painel, e todos os outros elementos que acabamos de construir são uma questão de design, então caso queira, você têm todo o direito de personalizar como preferir. Até mesmo a fonte pode ser diferente; basta acessar qualquer site, como o Google Fonts, por exemplo, onde você pode baixar a fonte que achar melhor, trazer para a Unity, e criar um "Font Asset" para ser aplicado posteriormente.

Alterando o background

Antes de continuar, vamos alterar o background, pois o fundo azul aplicado no momento não fica tão interessante, como podemos conferir na aba Game.

Para fazer isso, clicamos em Main Camera no painel Hierarchy, vamos até o campo "Background" na aba "Inspector" à direita, e depois acessamos a pasta "Assets > _external > kenney_abstract-platformer > PNG > Backgrounds". Feito isso, vamos alterar a cor de fundo para bege (set1_background). Dessa forma, temos uma estética mais bonita para o nosso jogo.

Criando o script MenuUI

Ao clicar no play da parte superior, notamos que os botões já podem ser clicados, mas ainda não temos nenhuma interação com eles. Vamos configurar isso agora, criando o script do menu.

Com a pasta "Scripts" selecionada, podemos clicar sobre ela com o botão direito e ir até "Create > Folder", para criar uma pasta chamada "UI". Agora, clicamos com o botão direito sobre "UI" e selecionamos "Create > C# Script" para criar o arquivo MenuUI.cs.

Já temos o código do menu pronto, então vamos apenas colar no arquivo e analisá-lo por partes.

Analisando o código do script

Primeiramente, criamos uma Header para facilitar a identificação na Unity e sabermos melhor quais são as propriedades. Abaixo, temos três SerializedField para os três botões, pois, dessa forma, conseguimos configurá-los diretamente pelo script.

MenuUI.cs:

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class MenuUI : MonoBehaviour
{
    [Header("Menu UI properties")]
    [SerializeField] private Button startButton;
    [SerializeField] private Button optionsButton;
    [SerializeField] private Button exitButton;

    // código omitido

Antes de passarmos pelo próximo trecho de código, queremos explicar que, na Unity, cada botão tem um componente de "Button" na aba "Inspector". Um pouco abaixo, temos o campo "On Click ()", onde configuramos qual ação o botão irá fazer. No entanto, não recomendamos usar essa opção ao criar um jogo que será mais escalável. Se mudarmos o nome da função no script, ou alterarmos o botão, por exemplo, a referência no editor também irá mudar e o que configuramos vai sumir em algum momento, o que pode trazer erros inesperados. Para evitar esse problema, realizamos a configuração do evento de clique diretamente pelo código.

Para configurar um evento por código, chamamos o botão seguido do evento onClick, e depois adicionamos um AddListener() para usar o evento. Entre parênteses, passamos a função desejada.

// código omitido

private void OnEnable()
{
    startButton.onClick.AddListener(GoToGameplayScene);
    exitButton.onClick.AddListener(ExitGame);
}

// código omitido

O AddListener() é o mesmo que usamos no arquivo InputManager.cs. É basicamente isso que fazemos no escopo de InputManager(). Observe abaixo:

// código omitido

public InputManager()
{
    playerControls = new PlayerControls();
    EnablePlayerInput();

    playerControls.Gameplay.Jump.performed += OnJumpPerformed;
    playerControls.Gameplay.Attack.performed += OnAttackPerformed;
}

// código omitido

Em seguida, temos a declaração das funções utilizadas nos métodos AddListener():

// código omitido

    private void GoToGameplayScene()
    {
        SceneManager.LoadScene("Gameplay");
    }

    private void ExitGame()
    {
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
#else
        Application.Quit();
#endif
    }
}

A função que passamos para o AddListener() do startButton foi a GoToGameplayScene(), responsável por nos levar para a cena de gameplay.

Importante! A biblioteca UnityEngine.UI importada no início do código é utilizada nos botões, então se ela não for adicionada automaticamente, será necessário importá-la manualmente.

Na função GoToGameplayScene(), vamos em SceneManager, chamamos o método LoadScene(), e vamos para a tela "Gameplay". Essa linha significa que iremos sair da cena de menu e iniciar a cena de gameplay, ou seja, vamos realizar uma transição entre cenas.

É muito importante saber usar o SceneManager e o LoadScene(), pois caso o jogo tenha vários níveis, chamaremos outros níveis dessa maneira o tempo inteiro. Existem formas mais profissionais e mais escaláveis, mas esta supre perfeitamente as nossas necessidades.

No botão exitButton, chamamos outra função, a ExitGame, cuja declaração está abaixo de GoToGameplayScene(). No escopo da função, encontramos uma configuração um pouco mais avançada, mas ela é muito importante para podermos testar o jogo e verificar se o botão funciona.

O bloco #if é um if de compilação, então quando o código for compilado, ele irá verificar se estamos no editor ou não. É basicamente isso que indicamos: se estivermos no editor (UNITY_EDITOR), vamos usar a linha do bloco #if para realizar a saída do jogo.

Caso contrário (bloco #else), ou seja, se o jogo já estiver "buildado" e em alguma loja, por exemplo, vamos fechar a aplicação chamando a função Quit() da classe Application.

Código completo do arquivo MenuUI.cs:

using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class MenuUI : MonoBehaviour
{
    [Header("Menu UI properties")]
    [SerializeField] private Button startButton;
    [SerializeField] private Button optionsButton;
    [SerializeField] private Button exitButton;

    private void OnEnable()
    {
        startButton.onClick.AddListener(GoToGameplayScene);
        exitButton.onClick.AddListener(ExitGame);
    }

    private void GoToGameplayScene()
    {
        SceneManager.LoadScene("Gameplay");
    }

    private void ExitGame()
    {
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
#else
        Application.Quit();
#endif
    }
}

Adicionando o script do menu na Unity

Para finalizar, vamos retornar ao editor da Unity e adicionar o script do menu (MenuUI.cs) no componente MenuUI. Após selecioná-lo no painel Hierarchy à esquerda, vamos até a aba "Inspector" e clicar no botão "Add Component" na parte inferior.

Feito isso, vamos selecionar a opção "Menu UI", clicar nos botões do painel Hierarchy, e arrastar para os respectivos campos de "Menu UI properties": StartButton para "Start Button"; OptionsButton para "Options Button"; e ExitButton para "Exit Button".

Menu UI properties

Agora, se clicarmos em play e depois no botão "SAIR", o jogo para de rodar. No entanto, ao clicar em "JOGAR", ainda falta uma configuração: precisamos ter a cena de gameplay.

Na pasta "Scenes", a cena de gameplay está nomeada como SampleScene. Vamos renomear para Gameplay. Assim, fica um pouco mais intuitivo para quando houver outras cenas no jogo. Feito isso, ao iniciar o jogo e clicar em "JOGAR" novamente, vamos para a cena Gameplay como esperado.

Conclusão

Ainda falta configurar o botão "OPÇÕES". Faremos isso no próximo vídeo!

Sobre o curso Unity: criando menus, coletáveis e batalha final em um jogo 2D

O curso Unity: criando menus, coletáveis e batalha final em um jogo 2D possui 227 minutos de vídeos, em um total de 61 atividades. Gostou? Conheça nossos outros cursos de Jogos em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Jogos acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas