Caso seja a primeira vez que acessa esta série, sinta-se à 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 a instalação e configuração da ferramenta até os conceitos que iremos abordar aqui, como a utilização de componentes Colliders e Triggers, assunto esse que foi abordado em nosso último tópico. Vamos juntos nesta caminhada rumo a novos conhecimentos!
Senso de desafio
Normalmente os jogos de videogame, computador e afins apresentam uma escalada gradual na dificuldade dos desafios propostos, como forma de estimular o gamer a continuar engajado na aventura. Não será diferente com o nosso jogo: vamos fazer com que a bolinha fique mais rápida gradativamente até um dos jogadores marcar um ponto.
Para isso, após a abertura do projeto Forest Ping Pong pelo editor do Unity, abra o script controladorBola (aba Project, dentro da pasta Scripts).
Vamos adicionar, logo abaixo das declarações de variáveis de direção e velocidade, uma nova variável:
internal float VelocidadeInicialBola;
Entre as chaves { } do método void Start() iremos adicionar a seguinte linha de código:
VelocidadeInicialBola = VelocidadeBola;
Também iremos adicionar, dentro do método void Update(), a seguinte linha de código:
VelocidadeBola = VelocidadeBola + 0.001f;
Confira se as adições foram realizadas conforme o exemplo da imagem ilustrativa anterior. Não se esqueça de salvar o script no Visual Studio.
A última linha de código já “denuncia” nossa intenção: pouco a pouco a velocidade irá subir e a dificuldade vai aumentar para rebater a bolinha no campo de jogo. Já as outras linhas de código farão mais sentido a partir da adição de parâmetros em outros scripts, tarefa essa que iremos começar agora.
Após salvar e minimizar o script no Visual Studio, volte ao Unity e abra o script de nome gol (aba Project, dentro da pasta Scripts).
No Visual Studio, após o código para voltar a bolinha ao centro da tela, vamos inserir o seguinte código:
// Ajustar velocidade da bolinha
other.gameObject.GetComponent<controladorBola>().VelocidadeBola = other.gameObject.GetComponent<controladorBola>().VelocidadeInicialBola;
Confira se as adições foram realizadas conforme ilustra a imagem abaixo e salve o script no Visual Studio.
Agora o código acrescentado anteriormente ao script controladorBola faz sentido: a variável VelocidadeInicialBola guardará em memória qual é a velocidade inicial da bola, assim que a partida começa. Quando um dos jogadores marca um ponto, a bolinha volta ao centro da tela com a sua velocidade restaurada ao “padrão inicial” e uma nova jogada começará a partir daquele momento.
Após salvar e minimizar o Visual Studio, experimente no Unity executar o jogo e veja a diferença. Não esqueça de, no final, encerrar a simulação, clicando novamente no botão Play.
E começa a partida!
O conteúdo de nosso jogo está praticamente pronto. Realizaremos agora algumas pequenas adições ao projeto para que possamos iniciar (ou reiniciar) nosso jogo de forma adequada.
Lembra-se de quando adicionamos um logo bem bonito no centro da barra de placar, contendo o nome do game? Pois bem, ele será nosso botão “liga/desliga” do jogo. Para isso, vamos criar um novo script cujo nome será inicializadorJogo. Assim como o realizado para a criação dos outros scripts, acesse a aba Project, dentro da pasta Scripts, e clique com o botão direito do mouse em uma área vazia, opção Create, C# Script.
Abra-o, clicando duas vezes sobre seu ícone. Vamos remover o conteúdo-padrão (métodos void Start() e void Update()), substituindo-o pelo código a seguir e, em seguida, salvando o script no Visual Studio:
public controladorBola Bolinha;
public UnityEngine.UI.Text TextoPlacarJogador, TextoPlacarAdversario;
public void ComecarPartida()
{
Bolinha.gameObject.transform.localPosition = new Vector2(0,0);
Bolinha.enabled = !Bolinha.enabled;
controladorJogo.PlacarJogador = 0;
controladorJogo.PlacarAdversario = 0;
TextoPlacarJogador.text = "Jogador: 0";
TextoPlacarAdversario.text = "Adversário : 0";
}
O que o código realizará é o posicionamento da bolinha no centro da tela de jogo, assim como zerar o placar e “ligar/desligar” o script controladorBola do objeto Bolinha. Mas como assim?
Note que, na linha que contém o código “Bolinha.enabled = !Bolinha.enabled”, estamos alterando o valor da variável enabled para seu inverso (é isso que o símbolo “!” faz, representa uma negativa ou inversão para variáveis do tipo booleanas). Ou seja, se o valor da variável enabled era "verdadeiro", agora será "falso", e o mesmo ocorre de forma inversa. A variável enabled representa se determinado componente ou objeto está ativo ou não.
Mas como podemos saber de forma prática se um script (ou outro componente qualquer de um objeto, com exceção do Transform) está ativo ou inativo? Volte ao Unity, clique no GameObject Bolinha e verifique essa pequena caixinha de seleção ao lado do nome do componente Controlador Bola, na aba Inspector:
Se ela estiver selecionada, o valor de enabled é "verdadeiro"; caso não esteja selecionada, enabled terá valor "falso" e o comportamento esperado do script (ou do componente em questão) não será executado. Na prática, em nosso caso, se o script Controlador Bola estiver “desligado”, a bolinha não irá sair deslizando pelo cenário e, de fato, não teremos uma partida iniciada.
Deixe a caixinha de seleção do script Controlador Bola sem seleção (em branco) e vamos prosseguir.
Selecione na aba Hierarchy o objeto IconeJunglePingPong (subordinado ao GameObject PlacarFundo). Vamos adicionar o componente Inicializador Jogo (aba Inspector, Add Component, Scripts).
Indique nos campos correspondentes quais são os GameObjects referentes ao Texto Placar Jogador (PlacarJogador), Texto Placar Adversario (PlacarAdversario) e Bolinha (Bolinha), conforme exemplo a seguir:
Um novo componente será exibido na aba Inspector. Clique em seu botão Add New Event Type e, em seguida, em PointerClick:
Abaixo da opção Runtime Only, clique no símbolo da bolinha de seleção. Na janela que for exibida, selecione a aba Scene e, em seguida, escolha IconeJunglePingPong.
No campo No Function, troque esse valor clicando sobre seu elemento, selecionando inicializadorJogo e, por fim, a função ComecarPartida().
O componente Event Trigger é responsável por realizar a execução de scripts ou a alteração de parâmetros a partir de eventos que são detectados. Em nosso caso específico, ele irá identificar o evento PointerClick (clique do mouse sobre o objeto) e irá solicitar a execução do método ComecarPartida(), presente no componente Inicializador Jogo do objeto IconeJunglePingPong. Dessa forma, ao clicarmos no ícone do jogo, a partida irá começar, caso não tenha ainda sido iniciada, ou será interrompida, caso esteja em andamento.
Um toque de alegria
Dentre os recursos que iremos utilizar com mais frequência em nossos próximos projetos, destacam-se as multimídias em geral, não apenas imagens como estamos utilizando neste game, mas também a aplicação de efeitos sonoros, trilhas e animações. Para darmos um “toque especial” ao nosso game, vamos realizar duas ações cosméticas: fazer com que a cabeça das cobrinhas acompanhe os movimentos realizados no teclado pelo jogador e, também, que seja reproduzido um pequeno efeito sonoro ao se marcar ou sofrer um ponto.
Primeiro, vamos às cobras: no Unity, na aba Project, dentro da pasta Scripts abra o arquivo correspondente ao script comportamentoCobrinha.
Dentro das chaves { } de “if (Input.GetKey(KeyCode.T))” e de “if (Input.GetKey(KeyCode.O))” adicione o seguinte trecho de código:
gameObject.transform.localScale = new Vector2(1,1);
Após a inserção, dentro das chaves { } de “if (Input.GetKey(KeyCode.G))” e de “if (Input.GetKey(KeyCode.L))” adicione o seguinte trecho de código:
gameObject.transform.localScale = new Vector2(-1,-1);
Esses códigos serão responsáveis pela “inversão” do desenho dos elementos gráficos do GameObject nos eixos X e Y. Na prática, quando o localScale de X e Y são iguais a -1, a imagem da cobrinha será desenhada na tela “de ponta cabeça”.
Salve os scripts, minimize o Visual Studio e teste o jogo no Unity (aba Game, botão Play), sem esquecer de interromper a simulação no final.
Ainda no Unity, na aba Scene, vamos adicionar um efeito sonoro para cada ponto ganho. Na aba Hierarchy, em um espaço vazio (mais abaixo, conforme imagem a seguir) clique com o botão direito do mouse, depois em Audio e, em seguida, Audio Source.
Dê ao objeto o nome de AudioPontoGanho. Na aba Inspector, selecione o AudioClip de nome moedinha e desmarque a opção Play On Awake, conforme ilustração a seguir:
Na aba Project, dentro da pasta Scripts, abra o script de nome gol. Acrescente abaixo da declaração de variáveis a seguinte linha de código:
public AudioSource AudioPonto;
Acrescente ao final do código do script, antes do fechamento das três chaves finais ( “}” ), o seguinte trecho de código:
// Tocar som para sinalizar ponto ganho:
AudioPonto.Play();
Salve o script, minimize o Visual Studio e volte ao Unity. Selecione os GameObjects GolEsquerda e GolDireita. Na aba Inspector, no campo correspondente ao componente Gol, selecione no campo AudioPonto o objeto AudioPontoGanho, conforme exemplo abaixo:
Agora, toda vez que for marcado um ponto, ao passar a bola pelas extremidades direita ou esquerda da tela, um pequeno som irá tocar, indicando a ação realizada. Experimente testar, veja e ouça o resultado de seu game!
Gerando um executável
Finalmente, chegou o grande momento de gerar os arquivos executáveis de nosso jogo e, assim, permitir altas jogatinas entre você e seus amigos, vizinhos, irmãos, parentes...
Primeiro, é importante salvar o projeto e a cena. Clique no menu File e, em seguida, em Save, para salvar a cena; posteriormente, clique no menu File e, em seguida, em Save Project, para salvar o projeto.
Uma pequena janela será aberta. Primeiro, clique em Add Open Scenes. No campo acima do botão, o nome da Cena01 irá aparecer, certifique-se de que a mesma está com sua caixinha selecionada. Depois, selecione a opção PC, Mac & Linux Standalone e, em seguida, clique no botão Build, conforme indicações da imagem a seguir:
Crie uma pasta em seu computador para armazenar os arquivos do jogo; neste exemplo criei uma pasta nova com o nome “Meu jogo 01 - Forest Ping Pong”. Selecione-a e clique no botão Selecionar pasta.
O processo de compilação (montagem) do game será iniciado e poderá demorar alguns minutos. Isso é normal.
Ao término do processo, a pasta em que seu jogo foi salvo será aberta. Basta clicar duas vezes sobre o arquivo “Forest Ping Pong.exe” e começará a diversão.
Melhorando seu código
Estão disponíveis no repositório GitHub do GameBlast os arquivos de uma versão já pronta (o “gabarito”) do projeto que desenvolvemos. Se quiser, baixe-os para comparar com o seu projeto.
Nesse gabarito, a fim de melhorar a legibilidade do código, os termos utilizados nos arquivos de script apresentam algumas alterações. Por exemplo, códigos como “transform.position.x = transform.position.x + 1” são substituídos por “transform.position.x += 1”, que, neste caso, de fato faz a mesma coisa (soma 1 ao valor da variável transform.position.x).
Não há uma regra fixa sobre a lógica utilizada no desenvolvimento de um game, porém sempre é recomendável tentar manter seus códigos legíveis e de fácil manutenção. Uma boa prática é adotar nomes condizentes com o que cada variável representa, evitando a utilização de nomes genéricos como “variavel_a”, “variavel_b”, a não ser em contextos específicos, como por exemplo a declaração de um inteiro “int i” para iteração dentro de uma estrutura for ou while.
Conclusão e próximos passos
Chegamos ao término de nosso primeiro projeto, dentro de nossa trilha de aprendizado na programação de jogos em Unity. Caso esteja lendo este texto no computador, se quiser pode testar o jogo diretamente de seu navegador para comparar o game com o que você desenvolveu. Será aberta em uma nova aba (ou janela) do seu navegador uma versão Web do jogo, o que também iremos aprender posteriormente a elaborar para nossos games.
Muitos dos conceitos apresentados durante os tópicos que iremos abordar de fato são um pouco complicados para serem entendidos à primeira vista. Se você teve alguma dificuldade ou não compreendeu muito bem algum ponto em específico, não se desestimule pois, com a prática obtida pela criação deste e dos próximos projetos, você acabará por compreender diversos conceitos e práticas que podem auxiliar a sanar suas dúvidas, totalmente normais nessa etapa do aprendizado.
Agora, conte-nos como está sendo para você até o momento: o espaço dos comentários aqui no GameBlast está aberto. Aguardo ansiosamente para ler o seu relato!
Em nosso próximo encontro iremos iniciar mais um projeto de desenvolvimento de game. Assim, praticando, poderemos aprender mais sobre algumas características interessantes de componentes como Canvas, Image, Sprites, Audio Source, além de outras abordagens envolvendo a detecção de eventos.
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