Um assunto muito importante mas pouco discutido dentro do mundo dos desenvolvedores de jogos é a utilização do NavMash. O que é algo estranho, já que a não utilização dessa ferramenta pode desencadear uma porção incalculável de bugs que seriam uma vergonha para o resto da vida. Agora, você deve estar se perguntando sobre qual ferramenta é essa que estamos falando, né?
Vou explicar. Certamente você já deve ter jogado algum game onde um dos NPCs fica travado em algum lugar, porém, correndo como se estivesse competindo na São Silvestre.
Se você já assistiu o filme Detona Ralph sabe que essa cena faz uma piada com um bug, o que era comum na época mas que persiste até hoje que é o de um personagem ser barrado por uma parede ou qualquer outro objeto, mas mesmo assim continuar andando.
Esse bug já era tosco na época e continua sendo até hoje. Só que o mais estranho é que mesmo com o passar dos anos os desenvolvedores pensam mais em efeitos visuais do que em evitar coisas desse tipo. Não é difícil evitar uma bizarrice dessa, game engines atuais geralmente oferecem uma forma simples de se contornar esse problema.
Então, nesse artigo, veremos como evitar esse tipo de problema em uma das game engines mais conhecidas e usadas no mundo, a Unity.
Se você não conhece a Unity, aconselho que visite o seguinte site:
Dê uma olhada em tudo o que essa fantástica ferramenta pode te oferecer, e tenho certeza que vai adorar, depois faça o download e continue lendo.
Ah, claro, se tiver interesse, temos alguns cursos sobre essa maravilhosa engine no TreinaWeb:
Curso Ruby on Rails Intermediário
Conhecer o cursoCom a Unity instalada, você vai ter a opção de criar um projeto. Selecione “Projetos 3D” e depois defina um nome e um local para salvá-lo.
Feito isso, nosso projeto será criado e teremos como resposta a seguinte imagem:
Veja que o projeto está vazio, tendo apenas alguns poucos objetos dentro de cena, como uma câmera e uma Luz. Então, para reproduzir um efeito NavMesh precisamos criar um pequeno cenário, onde podemos usar uma Plane como chão, alguns cubos como obstáculos e um cilindro para representar um personagem. Então, mãos à obra!
Primeiro, para criar uma plane para chão, é necessário ir no menu superior na opção GameObject => 3D Object => Plane.
Feito isso, você vai ter uma plane adicionada à sua cena, como mostra a imagem abaixo:
Agora, para criar os cubos que vão servir de obstáculos, é preciso ir novamente ao menu superior em GameObject => 3D Object => Cube.
Isso fará com que um cubo seja criado dentro da nossa cena, como mostra a imagem abaixo:
Repita esse processo algumas vezes para criar um número de obstáculos que deixe o exemplo mais interessante.
Veja que no meu caso criei 4 cubos.
Ok, até esse ponto tudo andando perfeitamente, mas a visualização da cena esta muito ruim, então vamos criar materiais para dar uma cor para o chão e para os cubos. Para fazer isso, basta ir na aba Project, clicar com o botão direito do mouse sobre a pasta Assets (àquela que é criada por padrão dentro da Unity).
Clique com o botão direito sobre essa pasta e selecione a opção Create => Material.
Isso vai criar um material padrão com a cor branca.
Veja que para esse material dei o nome de “Chão”, seguindo essa mesma lógica, vou criar mais um material com o nome de “obstáculo”.
Veja:
Agora, basta mudar as cores de cada material e depois aplicar em cada objeto dentro da cena. Para mudar a cor do material é muito simples, clique na caixa de cor branca ao lado de Albedo.
Na caixa de seleção de cores escolha uma cor para o chão e depois repita esse processo para adicionar uma cor para o obstáculo.
Veja:
Agora, clique e arraste cada um desses materiais para seus devidos objetos em cena para que seja possível conseguir um resultado como o exibido na imagem abaixo:
Estamos com a nossa cena pronta. Vamos adicionar um caminho para ser percorrido. Para que isso seja feito é necessário antes de tudo determinar todos os objetos de cena como estáticos. Isso é feito selecionando cada um deles e deixando marcado a opção Static.
Agora nos resta criar o caminho a ser percorrido pelo personagem. Esse caminho é criado com auxílio da janela Navigation que se não estiver em evidência pode ser adicionada à interface da Unity clicando em Window => Navigation.
Prontinho! Agora essa janela estará disponível na Unity como podemos ver na imagem abaixo:
Para criar o caminho é muito simples, apenas clique em Bake e veja a mágica acontecer:
Veja que no chão da nossa cena foi criado um caminho em azul claro, isso significa que o personagem só vai andar sobre aquela região, sendo possível identificar os obstáculos e analisar as melhores rotas para chegar em um determinado local.
Agora, vamos criar um personagem para percorrer esse caminho. Crie um cilindro dentro dessa cena indo até o menu superior GameObject => 3D Object => Cylinder.
Vamos posicionar esse cilindro na cena, como mostra a imagem abaixo:
Para que tenhamos efeitos físicos nesse objeto, precisamos adicionar a ele um componente chamado RigidBody que oferece características físicas ao cilindro, fazendo com que o mesmo sofra com a força da gravidade, por exemplo.
Agora vamos adicionar o NavMeshAgen. Esse componente pode ser adicionado ao cilindro indo até o menu superior em Component => Navigation => NavMeshAgent.
Ele atribui ao cilindro algumas características como aceleração, velocidade entre outras que podemos notar na imagem abaixo:
Maravilha! Agora sim fechamos a etapa de construção do NavMesh de sua forma visual. Para finalizar, vamos criar um código para fazer com que tudo isso ganhe vida.
Para criar o código é necessário ir na aba Project dentro da pasta Assets e criar um arquivo de código C# ou JS, no meu caso vou criar um C# veja:
Veja que para criar um arquivo de código é muito simples, basta clicar com o botão direito sobre a pasta Assets, depois em Create e por fim escolhemos o tipo de código que o arquivo deve ter. Com o arquivo criado, podemos dar um nome para ele, no meu caso o chamei de NavScript.
Clique duas vezes sobre ele para abri-lo e escreva o seguinte código:
using UnityEngine;
using System.Collections;
public class NavScript : MonoBehaviour {
private NavMeshAgent Agent;
public Transform Alvo;
void Start () {
Agent = GetComponent<NavMeshAgent> ();
}
// Update is called once per frame
void Update () {
Agent.SetDestination (Alvo.position);
}
}
Veja que a primeira coisa que fiz foi criar dois atributos onde um pega o NavMeshAgent e o outro pega o alvo que será o local onde o cilindro precisa chegar.
private NavMeshAgent Agent;
public Transform Alvo;
Depois em Start() é necessário pegar o componente do NavMeshAgent com a seguinte linha de código:
Agent = GetComponent<NavMeshAgent> ();
E por fim, em Update(), vamos adicionar o código que faz com que o cilindro se movimente até chegar no alvo.
Agent.SetDestination (Alvo.position);
Nesse momento, você deve estar um pouco confuso, não? Afinal, não falamos de nenhum alvo na construção da nossa cena, né? Mas, tudo bem, isso será criado agora!
Dentro da cena vamos criar um cubo que será o alvo. Veja:
Aí está! Esse cubo é o alvo do nosso cilindro. Agora vamos adicionar o código que criamos ao cilindro. Para fazer isso, basta “arrastar” o código sobre o cilindro. Depois disso, com o cilindro selecionado, vamos adicionar ao campo de alvo o cubo que acabamos de criar, também arrastando o cubo até o local apresentado na imagem abaixo.
Pronto! Agora é só executar o exemplo e ver tudo funcionando. Espero que tenham gostado dessa dica Gamer. =)
Até a próxima!