Desenvolvimento Unity

Tutorial de como criar o jogo Arkanoid na Unity 2D

Prefácio:

Vamos fazer um clone do Arkanoid com apenas 37 linhas de código ! O Arkanoid original foi lançado há muito tempo em 1986, mas ainda é altamente viciante e graças à sua natureza de estilo arcade é muito fácil de desenvolver em Unity.

Como sempre, tudo será explicado da forma mais fácil possível para que todos possam entender.

Aqui está uma prévia do jogo final:

Requisitos:

Conhecimento

Este é um tutorial para iniciantes onde nenhuma habilidade avançada é necessária. Apenas o básico do Unity é útil para saber. Se você não conhece os fundamentos do Unity, sinta-se à vontade para tentar ver até onde você chega ou assistir um video do canal DFILITTO.

Versão da unidade

Nosso tutorial 2D Arkanoid usará Unity 2018.3.14f1 . Versões mais recentes também devem funcionar bem, mas observe que versões mais antigas do Unity podem não funcionar conforme descrito neste tutorial. Para melhores resultados, mantenha as versões 2018.3 .

Inicialização do Projeto

Nota: As capturas de tela mostradas no Unity Hub são da versão 2.x. As versões mais antigas parecerão diferentes, mas são basicamente as mesmas. Alguns elementos nas versões mais antigas são menus suspensos em vez do novo layout visual.

Vamos fazer um jogo! Iniciaremos o Unity Hub e selecionaremos Novo Projeto :

Vamos chamá-lo de arkanoid , selecione qualquer local como C:\GameDev , selecione 2D e clique em Create Project :

Nota: É sempre recomendável garantir acesso de gravação à pasta do seu projeto. Devido à proteção do sistema (e/ou restrições), o Windows às vezes fará com que se recuse a criar pastas na pasta raiz do disco rígido, fazendo com que o Unity gere erros de acesso negado. Se você receber esse erro, tente uma pasta diferente – por exemplo, C:\Users\YourUserName\GameDev geralmente funciona, ou uma pasta em uma unidade de disco dedicada.

Não é recomendado colocar o Projeto Unity em uma pasta onde será feito backup na nuvem, pois isso pode causar erros inesperados durante o desenvolvimento (como arquivos bloqueados e outros erros aleatórios)!

Configuração do projeto

Agora podemos ajustar a câmera às nossas necessidades. Primeiramente selecionamos o GameObject da Câmera Principal na Hierarquia , depois ajustamos a Cor de Fundo para algo escuro e modificamos o Tamanho como mostrado na imagem a seguir:

Obs: o tamanho é praticamente o fator de zoom da câmera. Nós o modificamos para que o jogo em geral pareça perfeito mais tarde.

O padrão de fundo hexágono

O jogo Arkanoid original usa um padrão hexágono azul como plano de fundo. Podemos criar um padrão semelhante com nossa ferramenta de desenho preferida:

Nota: clique com o botão direito na imagem, selecione Salvar como… , navegue até a pasta Assets do projeto e salve-o em uma nova pasta Sprites .

Vamos selecionar a imagem do padrão hexágono na área do projeto :

E então modifique as configurações de importação no Inspetor :

Nota: isso informa ao Unity como carregar a imagem, qual compactação usar (nenhuma no nosso caso), usar a filtragem de pontos (isso evita estranhezas) e qual o tamanho que ela deve ter no jogo final (exatamente o mesmo tamanho no nosso caso).

Agora podemos arrastar a imagem hexágono da área do projeto para a hierarquia para torná-la parte do mundo do jogo:

Nota: certifique-se de que o padrão hexágono não faça parte da câmera principal. Tente arrastar e soltar em uma parte vazia do Inspetor.

Até agora, tudo bem, mas ainda não terminamos. Prepare-se para a próxima missão!

A camada de classificação

Estamos fazendo um jogo 2D e haverá situações em que várias imagens serão desenhadas umas sobre as outras, por exemplo, quando a bola e o padrão hexágono forem desenhados.

Vamos dizer ao Unity que nosso padrão hexágono deve estar em segundo plano para garantir que a bola seja sempre desenhada em cima dele (portanto, visível) .

Podemos usar uma camada de classificação para isso. Podemos alterar a camada de classificação do padrão hexágono se dermos uma olhada no componente Sprite Renderer no Inspector :

Vamos selecionar Adicionar camada de classificação . ​o topo da lista:

Agora podemos selecionar o padrão hexágono novamente e atribuir a ele nossa nova camada de classificação de fundo :

Salve seu trabalho. Um bom desenvolvedor de jogos salvará regularmente seu trabalho para evitar perda de dados. Você pode ir em Arquivo -> Salvar ou pressionar Control + S juntos ( Command + S no Mac OS) para salvar a cena.

Adicionando as bordas

As Imagens da Fronteira

Adicionaremos bordas para garantir que a bola não saia voando do jogo. Precisaremos de uma imagem para cada borda:

Nota: clique com o botão direito em cada imagem, selecione Salvar como… e salve todas na pasta Assets/Sprites do projeto.

Configurações de importação de borda

Usaremos as mesmas configurações de importação que usamos antes:

Agora podemos arrastar as bordas da Área do Projeto para a Hierarquia e então posicioná-las na Cena para que fiquem fora da imagem hexagonal:

Física Fronteiriça

Neste momento as nossas fronteiras são apenas imagens. Para fazer a bola colidir com eles teremos que adicionar um Collider em cada borda. Podemos fazer isso selecionando-os primeiro na Hierarquia :

Depois podemos dar uma olhada no Inspetor e selecionar Add Component -> Physics 2D -> Box Collider 2D :

Agora as fronteiras fazem parte do mundo da física. Eles ainda parecem exatamente iguais, mas em vez de serem apenas uma imagem, agora também são paredes físicas (por causa do Collider) .

A Raquete

A imagem da raquete

Vamos criar a raquete (chamada Vaus no jogo original) . O jogador poderá movimentar a raquete horizontalmente para evitar que a bola caia fora do jogo.

Como de costume começaremos desenhando uma imagem de raquete:

Nota: clique com o botão direito na imagem, selecione Salvar como… e salve na pasta Assets/Sprites do projeto.

Importando a raquete

Usaremos as mesmas configurações de importação que usamos para todas as outras imagens em nosso tutorial Arkanoid:

Agora podemos arrastar a raquete da área do projeto para a hierarquia e posicioná-la na parte inferior do nosso jogo:

Observação: você também pode definir os valores de transformação XYZ diretamente usando o conjunto de valores Posição no inspetor de raquetes se estiver tendo problemas para alinhá-lo. Um valor sugerido para eles é: X 0, Y -95, Z 0.

Salve seu trabalho.

Física da Raquete

Como antes, queremos que a raquete faça parte do mundo da física porque a bola deverá colidir com ela mais tarde. Vamos selecionar a raquete na Hierarquia e depois pressionar Add Component -> Physics 2D -> Box Collider 2D no Inspector :

Há mais um pouco de física para fazer. O jogador deverá ser capaz de mover a raquete para a esquerda e para a direita, e tudo no mundo da física que supostamente se move precisará de um Rigidbody . Um Rigidbody cuida de todos os tipos de coisas como velocidade e gravidade, mas por enquanto basta lembrar que tudo que é físico que se move pelo mundo do jogo precisará de um Rigidbody .

Podemos adicionar um Rigidbody à raquete selecionando Add Component -> Physics 2D -> Rigidbody 2D no Inspector . Depois, definimos as seguintes configurações:
– Escala de Gravidade: 0 (evita que a raquete caia fora dos limites)
– Detecção de colisão: Contínua (evita falhas onde a bola pode passar pela raquete devido a peculiaridades do motor Physics 2D)
– Freeze Rotation on o Eixo Z: faz com que a raquete congele seu ângulo. Deixar esta opção desmarcada pode fazer com que a raquete gire no eixo Z quando a bola colide com a raquete, o que pode ser bastante divertido no início, mas logo se tornará muito irritante.

Parabéns por chegar até aqui! Não se esqueça de salvar seu trabalho. Estamos um pouco mais da metade do caminho.

Movimento da Raquete

O jogador deve ser capaz de mover a raquete horizontalmente. Esse tipo de recurso pode ser adicionado com Scripting . Vamos selecionar Add Component -> New Script no Inspector , nomeá-lo Racket e clicar no botão “Criar e Adicionar”:

O Unity então cria o novo Script e o adiciona automaticamente à nossa raquete. Vamos também dar uma olhada em nossa Área de Projeto e mover o Script para uma nova pasta Scripts , apenas para manter tudo limpo:

Vamos abrir o Script clicando duas vezes nele. Isso deverá abrir o Visual Studio ou outro editor de código se você estiver em uma plataforma diferente. Aqui está como parece:

using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

Nossa função Start é chamada automaticamente pelo Unity ao iniciar o jogo. Nossa função de atualização é chamada automaticamente repetidamente, aproximadamente vinculada à taxa de quadros do jogo, que é definida como 60 por padrão.

Existe ainda outro tipo de função Update , chamada FixedUpdate . Também é chamado repetidamente, mas em um intervalo de tempo fixo. A Física do Unity é calculada exatamente no mesmo intervalo de tempo, por isso é sempre uma boa ideia usar o FixedUpdate ao fazer cálculos relacionados à Física, já que nossa Racket é um objeto de Física (já que possui um Rigidbody).

Podemos remover as funções Start e Update e criar uma função FixedUpdate agora:

using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {

    void FixedUpdate () {

    }
}

Nota: é importante nomeá-lo exatamente como FixedUpdate porque esse é o nome que o Unity espera. Também podemos criar funções com nomes diferentes, mas elas não seriam chamadas automaticamente pelo Unity.

Usaremos a propriedade de velocidade do Rigidbody para fazer a raquete se mover. A velocidade é sempre a direção do movimento multiplicada pela velocidade do movimento . É do tipo Vector2 e aqui estão alguns exemplos de Vector2:

Vamos adicionar uma variável Speed ​​ao nosso Script:

using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {
    // Movement Speed
    public float speed = 150;

    void FixedUpdate () {

    }
}

O jogador deve ser capaz de mover a raquete pressionando as teclas de seta direita / esquerda , ou as teclas A / D , ou talvez até mesmo o stick de um gamepad. Poderíamos verificar todas essas chaves manualmente ou usar a função GetAxisRaw do Unity para obter a entrada horizontal . Ele retornará -1 para Left , 0 para sem direção, também conhecido como posição netural e 1 para right:

void FixedUpdate () {
    // Get Horizontal Input
    float h = Input.GetAxisRaw("Horizontal");
}

Agora podemos definir a velocidade para a direção do movimento multiplicada pela velocidade:

void FixedUpdate () {
    // Get Horizontal Input
    float h = Input.GetAxisRaw("Horizontal");

    // Set Velocity (movement direction * speed)
    GetComponent<Rigidbody2D>().velocity = Vector2.right * h * speed;
}

Nota: acessamos o componente Rigidbody2D que anexamos ao nosso Racket usando a função GetComponent . Depois calculamos a direção multiplicando Vector2.right por h . Se h for -1 , resultará em -Vector2.right (que fica à esquerda). Se h for 0 , resultará em Vector2.zero (que não tem direção). Se h fosse 1 , isso resultaria em Vector2.right (que está certo). Depois multiplicamos pela velocidade para que se mova rápido o suficiente.

Isso é tudo que tivemos que fazer para fazer a raquete se mover. Se pressionarmos play, agora podemos mover a raquete:

Vamos prosseguir para fazer a bola se mover.

A bola

A imagem da bola

É hora de adicionar a bola. Como antes, começaremos desenhando algum tipo de bola imaginável:

Obs: clique com o botão direito na imagem, selecione Salvar como… e salve na pasta Assets/Sprites do projeto.

Usaremos as seguintes configurações de importação para a imagem da bola:

Depois podemos arrastar a bola da Área do Projeto para a Hierarquia para adicioná-la ao nosso mundo de jogo. Vamos posicioná-lo um pouco acima da raquete:

O Colisor de Bolas

A bola deve fazer parte do mundo da física, então vamos selecioná-la na Hierarquia e depois pressionar Adicionar Componente -> Física 2D -> Box Collider 2D para adicionar um Collider:

A bola também deve quicar nas paredes. Se voar diretamente em direção a uma parede, deverá ricochetear na direção oposta. Se atingir a parede em um ângulo de 45° , deverá ricochetear em um ângulo de -45° (e assim por diante) . A matemática por trás disso é bastante fácil e pode ser feita com um Script, mas faremos isso da maneira mais fácil possível, atribuindo um Material de Física ao Ball Collider. Os materiais físicos contêm informações sobre os aspectos físicos dos colisores, como fricção e elasticidade .

Vamos clicar com o botão direito na Project Area , escolher Create -> Physics Material 2D e nomeá-lo BallMaterial :

Depois podemos dar uma olhada no Inspetor e ajustar as propriedades do material para fazê-lo ricochetear:

Agora só temos que arrastar o material da Área do Projeto para o slot Material do Ball’s Collider:

Agora a bola irá quicar quando atingir uma parede.

A bola de corpo rígido

A bola já faz parte do mundo da física, mas tudo que se move deve sempre ter um Rigidbody preso a ela. Podemos adicionar um à nossa bola selecionando Add Component -> Physics 2D -> Rigidbody 2D no Inspector .

Faremos as seguintes alterações conforme mostrado abaixo:

  • Massa: 0,0001 (isso ajudará a evitar que a bola empurre a raquete)
  • Escala de Gravidade: 0 (isso impedirá que a bola use a gravidade)
  • Interpolação: Interpolar (para tornar a Física o mais exata possível)
  • Detecção de colisão: Contínua (ajuda a evitar erros de colisão devido às peculiaridades do mecanismo Unity Physics 2D)

Nota: as modificações podem parecer coisas de física avançada, mas não se preocupe. A maneira comum de descobrir essas configurações é testando o jogo e modificando o Rigidbody passo a passo para obter os efeitos desejados.

Se apertarmos Play agora, a bola não se moverá, porque não tem velocidade padrão. Vamos selecionar Add Component -> New Script no Inspector , nomeá-lo Ball e selecionar o botão Create and Add . Também iremos movê-lo para nossa pasta Scripts na Área do Projeto e então abri-lo:

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

Não precisaremos da função Update , então vamos removê-la:

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }
}

Vamos usar a propriedade de velocidade do Rigidbody para fazê-lo mover-se para cima em uma certa velocidade :

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {
    // Movement Speed
    public float speed = 100.0f;

    // Use this for initialization
    void Start () {
        GetComponent<Rigidbody2D>().velocity = Vector2.up * speed;
    }
}

Podemos apertar play para ver a bola quicar nas bordas:

A bola <-> Ângulo de colisão da raquete

Já estamos nos aproximando da linha de chegada. Agora adicionaremos um recurso interessante de jogo à colisão entre bola e raquete. Queremos que o jogador tenha algum controle sobre o ângulo de saída da bola quando ela atinge a raquete:

Vamos abrir o script da bola para que possamos implementar o recurso do ângulo de saída. Usaremos a função OnCollisionEnter2D do Unity que é chamada automaticamente pelo Unity sempre que a bola colide com outra coisa:

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {
    // Movement Speed
    public float speed = 100.0f;

    // Use this for initialization
    void Start () {
        GetComponent<Rigidbody2D>().velocity = Vector2.up * speed;
    }

    void OnCollisionEnter2D(Collision2D col) {
        // This function is called whenever the ball
        // collides with something
    }
}

Precisaremos de algum tipo de código que calcule a velocidade da bola dependendo de onde ela atingiu a raquete.

O valor de y será sempre 1 , porque queremos que ele voe para cima e não para baixo. O valor de x requer alguma reflexão. Será algo entre -1 e 1 , mais ou menos assim:

1  -0.5  0  0.5   1  <- x value depending on where it was hit
===================  <- this is the racket

Tudo o que precisamos fazer é descobrir onde está a bola, em relação à raquete. Podemos fazer isso simplesmente dividindo a coordenada x da bola pela largura da raquete . Aqui está nossa função para isso:

float hitFactor(Vector2 ballPos, Vector2 racketPos,
                float racketWidth) {
    // ascii art:
    //
    // 1  -0.5  0  0.5   1  <- x value
    // ===================  <- racket
    //
    return (ballPos.x - racketPos.x) / racketWidth;
}

Nota: subtraímos o valor racketPos.x do valor ballPos.x para obter a posição relativa.

Aqui está nossa função OnCollisionEnter2D final :

void OnCollisionEnter2D(Collision2D col) {
    // Hit the Racket?
    if (col.gameObject.name == "racket") {
        // Calculate hit Factor
        float x=hitFactor(transform.position,
                          col.transform.position,
                          col.collider.bounds.size.x);

        // Calculate direction, set length to 1
        Vector2 dir = new Vector2(x, 1).normalized;

        // Set Velocity with dir * speed
        GetComponent<Rigidbody2D>().velocity = dir * speed;
    }
}

Nota: leia os comentários para entender o que está acontecendo.

Se apertarmos play, agora podemos influenciar a direção do salto da bola dependendo de onde ela atingiu a raquete.

Adicionando Blocos

É hora de alguns blocos. Afinal, Arkanoid é chato sem algo para destruir.

Usaremos as seguintes imagens para nossos blocos:

  • Azul:Bloco Azul
  • Verde:Bloco Verde
  • Rosa:Bloco Rosa
  • Vermelho:Bloco Vermelho
  • Amarelo:Bloco Amarelo

Nota: clique com o botão direito em cada imagem, selecione Salvar como… e salve todas na pasta Assets/Sprites do projeto.

Vamos selecionar a imagem do bloco vermelho em nossa Área do Projeto e então usar estas Configurações de Importação no Inspetor :1

Nota: Use os mesmos valores mostrados aqui para os sprites do bloco Verde, Rosa, Amarelo e Azul.

Como antes, agora podemos arrastá-lo da Área do Projeto para a Hierarquia e posicioná-lo no canto superior esquerdo do nosso jogo:

Para que o bloco faça parte do mundo da física, selecionaremos Adicionar Componente -> Física 2D -> Box Collider 2D no Inspetor :

Queremos que o bloco seja destruído após ser atingido pela bola. Este tipo de comportamento é sempre implementado com um Script. Vamos selecionar Adicionar Componente -> Novo Script no Inspetor , nomeá-lo Bloco e clicar no botão “Criar e Adicionar”. Iremos movê-lo para nossa pasta Scripts novamente conforme mostrado anteriormente e então abri-lo:

using UnityEngine;
using System.Collections;

public class Block : MonoBehaviour {

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }
}

Podemos remover as funções Iniciar e Atualizar , porque não precisaremos delas. Já estamos familiarizados com a função OnCollisionEnter2D , então vamos usá-la novamente:

using UnityEngine;
using System.Collections;

public class Block : MonoBehaviour {

    void OnCollisionEnter2D(Collision2D collisionInfo) {
        // Destroy the whole Block
        Destroy(gameObject);
    }
}

Nota: Destroy(this) destruiria apenas o componente Block Script. Se quisermos destruir o Bloco inteiro, sempre teremos que usar Destroy(gameObject) , que destrói o próprio GameObject do Bloco.

Depois podemos duplicar o bloco algumas vezes (selecione-o na Hierarquia e depois pressione Ctrl + D ou clique com o botão direito -> Duplicar ) e então posicione as cópias em algum outro lugar da Cena:

Repetiremos esse processo para cada uma das diferentes imagens de cores de bloco em nosso Projeto:

Nota: podemos reutilizar nosso Block Script para os outros Blocos também.

E é isso! Se apertarmos o play, poderemos aproveitar o resultado incrível do nosso tutorial do Unity 2D Arkanoid:

Salve seu trabalho. Você não quer que seu trabalho duro seja desfeito por uma falha repentina do Unity ou alguma outra falha.

Parabéns, você completou seu próprio jogo Arkanoid 2D!

Resumo

Acabamos de aprender como fazer um belo clone de Arkanoid no Unity. Criamos um projeto rápido, limpo e de última geração. Como sempre, agora cabe a você tornar o jogo mais divertido. Aqui estão algumas idéias de melhoria:

  • Um som de colisão
  • Mais níveis
  • Blocos Indestrutíveis
  • Atualizações de tamanho de raquete
  • Um ponto
  • Uma tela de ganhar e perder
  • Um menu

Os jogos arcade são a melhor maneira de aprender como desenvolver um jogo e como torná-lo divertido. Não tenha pressa, brinque com ele e torne-o incrível!

E ai, esta gostando da área de games? Então que tal se tornar um desenvolvedor de jogos completo com o curso Desenvolvedor de Jogos 2D e 3D. Neste curso você irá aprender na prática tudo sobre Game Design, Criação de artes para jogos, Lógica de Programação, Programação Orienta a Objetos e é claro, criar seus próprios jogos utilizando a Engine Unity.

FONTE: Esse texto foi retirado do site https://noobtuts.com/unity,

Super Dicas

Venha conhecer os nossos cursos da Hotmart Clube e Udemy.

Se inscreva em nosso canal, compartilhe as matérias que gostar com os seus colegas, e participe da nossa comunidade no Telegram.

Aproveite também e venha fazer parte do nosso clube de vantagens e ter acesso exclusivo a vídeos, tutoriais, cursos e muito mais. Clique no link para se tornar um membro do dfilitto – clube de vantagens e ter acesso a todos os benefícios do nosso clube.

Matheus Correia Augusto da Silva

Me chamo Matheus Correia, tenho 21 anos e curso graduação em Marketing, faculdade na qual termino em junho, em breve será lançado um livro no qual faço parte.
Faço estágio na empresa Micro2000 e faço parte do marketing de criação de imagens para redes sociais.

Assinar blog por e-mail

Digite seu endereço de e-mail para assinar este blog e receber notificações de novas publicações por e-mail.

Junte-se a 2.252 outros assinantes

Anúncios

Aprenda a criar seus jogos com os melhores desenvolvedores de jogos

Advertisement

Quer aprender a programar?