Ambientes 2D isométricos com Tilemap

Com o lançamento do Unity 2018.3, introduzimos o suporte ao Isometric Tilemap, seguindo de perto o suporte ao Hexagonal Tilemap, que foi adicionado na versão 2018.2. Os novos recursos do Tilemap oferecem uma maneira rápida e eficiente de criar ambientes 2D com base em layouts de grade isométrica e hexagonal, como os vistos em muitos jogos clássicos, incluindo as primeiras entradas das franquias Diablo e Fallout, Civilization, Age of Empires e muitos outros. Ambos os recursos são baseados no sistema Tilemap existente introduzido no Unity 2017.2, e trabalhar com eles hoje em dia é igualmente fácil! Eles também são integrados nativamente ao Editor. Em versões futuras do Unity, eles poderão ser movidos para o gerenciador de pacotes. Se você tiver interesse em acompanhar e experimentar as técnicas mostradas, criamos um projeto pré-configurado do Isometric Starter Kit com um personagem animado e vários conjuntos de ambientes, que você pode baixar gratuitamente.
Explore mais ambientes 2D e ferramentas que oferecem infinitas possibilidades criativas
Antes de começarmos a trabalhar com o Tilemap, é importante configurar nosso projeto corretamente. O Isometric Tilemap funciona com sprites bidimensionais e depende da classificação correta do renderizador para criar a ilusão de uma visão isométrica de cima para baixo. Precisamos garantir que os ladrilhos que estão mais distantes do observador sejam pintados primeiro; e os que estão mais próximos sejam pintados por cima deles.
Para personalizar a ordem em que os objetos 2D são pintados na tela, podemos usar o recurso Custom Axis Sort do Unity. Você pode definir essa configuração por câmera (atualmente, essa é a maneira padrão de fazer isso nos Pipelines de Renderização Scriptáveis, incluindo LWRP e HDRP) ou globalmente no nível do projeto.
Para definir uma Classificação por Eixo Personalizada no nível do Projeto, vá para Editar > Configurações do Projeto > Gráficos. Na seção Configurações da câmera, você verá um menu suspenso Modo de classificação por transparência, bem como as configurações de valores X, Y e Z para o Eixo de classificação por transparência.
Por padrão, o Eixo de Classificação de Transparência no Unity é definido como (0, 0, 1) para XYZ, respectivamente. No entanto, todos os nossos blocos 2D estão, na verdade, no mesmo plano Z. Em vez disso, podemos determinar quais peças estão atrás ou na frente usando sua altura na tela, em vez de sua profundidade. As peças posicionadas mais acima na tela serão classificadas atrás daquelas posicionadas mais abaixo. Para classificar os blocos com base na altura, altere o Modo de classificação por transparência para Personalizado e defina os valores do Eixo de classificação por transparência como (0, 1, 0).

Você pode ler a página de documentação relevante do Unity para classificação 2D se quiser saber mais sobre como ela funciona.
Em alguns casos, você também pode querer ajustar o valor Z do seu Eixo de Classificação por Transparência. Abordaremos isso com mais detalhes mais adiante neste post do blog.
O recurso Tilemap consiste em vários componentes trabalhando juntos. Os dois primeiros são os objetos de jogo Grid e Tilemap. Para criar uma grade, basta clicar com o botão direito em qualquer lugar da hierarquia, ir em Objeto 2D e selecionar o tipo de Tilemap que deseja usar. Por padrão, cada nova grade é criada com um objeto de jogo Tilemap filho do tipo correspondente. Os tipos de Tilemap disponíveis atualmente são os seguintes:
Tilemap - cria uma grade retangular e um Tilemap. Um exemplo do uso deste Tilemap pode ser visto no 2D Game Kitda Unity.
Mapa de blocos com ponto hexagonal superior - cria uma grade hexagonal e um mapa de blocos, onde um dos vértices de cada hexágono aponta para cima.
Mapa de blocos de topo plano hexagonal - outro tipo de grade hexagonal, onde o topo do hexágono é uma aresta paralela ao topo da tela.
Os dois últimos tipos, Isométrico e Isométrico Z como Y, criam duas implementações diferentes da grade isométrica. A diferença entre eles surge ao simular diferentes níveis de elevação de peças, como quando temos uma plataforma elevada em nosso nível isométrico.
Um Tilemap Isométrico regular é melhor utilizado quando você deseja criar Objetos de Jogo Tilemap separados para cada nível de elevação individual dos tiles. Isso simplificará o processo de criação de formas de colisão automáticas, mas você terá menos flexibilidade quando se trata de variação de altura entre os blocos, já que todos os blocos em uma camada terão que estar no mesmo "plano".
No caso de um Tilemap isométrico Z como Y, o valor da posição Z de cada bloco funciona em combinação com a configuração personalizada de classificação do eixo de transparência para fazer com que os blocos pareçam empilhados uns sobre os outros. Ao pintar em um Z como Y Tilemap, ajustamos dinamicamente a configuração Z no pincel para alternar entre diferentes alturas. O Tilemap Z como Y requer um valor Z adicional no Eixo de Classificação de Transparência Personalizada para renderizar corretamente.

Observação: Os recursos mostrados aqui são do conjunto de peças do Templo em nosso projeto Kit Inicial Isométrico . Sinta-se à vontade para baixá-lo - totalmente gratuito - e divirta-se criando seus próprios ambientes!
Pense na grade como o "cavalete" que segura seus objetos de jogo Tilemap - que são essencialmente telas nas quais você pintará seus blocos. Para começar a pintar em um Tilemap, você também precisa de um pincel e uma paleta. Uma paleta de ladrilhos é o que contém seus ativos de ladrilhos, depois dos quais você pode selecioná-los com a ferramenta pincel e começar a pintar.
Para criar uma Paleta de Blocos, escolha Janela > 2D > Paleta de Blocos. Na janela recém-aberta, no menu suspenso superior esquerdo, escolha “Criar nova paleta”. Certifique-se de definir o tipo de grade que corresponde ao seu caso de uso. Para este exemplo, usarei um Tilemap isométrico regular, bem como os ativos do nosso projeto Isometric Starter Kit. Defina o tamanho da célula da paleta como Manual para poder personalizar as dimensões dos seus blocos isométricos. Neste caso, sei que as dimensões dos meus blocos correspondem a uma grade de 1 em X e 0,5 em Y; no entanto, para seu caso de uso, isso dependerá da resolução, dos valores de pixels por unidade selecionados na importação e das dimensões dos ativos - essencialmente, do ângulo isométrico no qual os blocos são girados.

Você pode não ter certeza sobre as configurações de importação corretas e o tamanho do mapa de blocos que funcionarão para seus ativos. Há uma regra geral que você pode seguir aqui com base nas dimensões iniciais dos seus ativos. Primeiro, observe a resolução dos seus blocos. Normalmente, peças isométricas representadas como um bloco são mais altas do que largas; peças "planas" (aquelas que parecem um plano em vez de um cubo) são mais largas do que altas. No entanto, a largura será sempre a mesma entre eles. Portanto, se você quiser que seus blocos ocupem exatamente uma unidade Unity, defina o valor Pixels por unidade nas configurações de importação de blocos igual à largura deles em pixels. Você pode querer ajustar esse valor em alguns casos - geralmente diminuindo-o (ou aumentando a resolução real dos seus ativos); isso pode ser útil se você estiver tentando produzir um efeito em que alguns blocos parecem ocupar mais de uma célula da grade e se sobrepõem aos blocos vizinhos.

Para decidir o valor correto da grade Y para os blocos, pegue a altura da base (ou tampa) de um único bloco e divida pela largura. Isso lhe dará um valor Y em relação a X, desde que X seja 1. Vejamos alguns exemplos:

Para a pixel art que estamos usando neste projeto, todos os blocos têm uma altura base de 32 pixels e 64 pixels de largura. Portanto, o tamanho da grade que usaremos é exatamente 0,5 em Y. O segundo bloco na imagem de exemplo vem de um pacote de ativos da Golden Skull Art. O bloco de exemplo foi reduzido para referência, mas os ativos originais têm 128 pixels de largura. A base do bloco tem cerca de 66 pixels de altura, o que nos dá um tamanho de grade Y de 66/128 - aproximadamente 0,515 unidades.
Depois de definir as dimensões corretas da grade, vamos adicionar alguns blocos à nossa paleta. Basta pegar um dos seus sprites de ladrilho e arrastá-lo para a janela Paleta de ladrilhos. Isso criará um Tile Asset. Ele contém algumas informações sobre o próprio bloco, como o(s) sprite(s) que ele está usando, uma cor de matiz e o tipo de colisor que ele irá gerar. Se quiser ver informações detalhadas sobre um bloco na paleta, escolha a ferramenta Selecionar (S) na parte superior da janela Paleta de Blocos e clique naquele bloco. Agora, no Inspetor, você poderá ver qual ativo do Tile ele está referenciando.
Para pintar o novo Tile no nosso Tilemap, selecione a ferramenta Pincel (B) e clique no Tile na Paleta. Agora você poderá pintar com o Tile selecionado na visualização de cena. Algumas outras ferramentas de pintura incluem a Borracha (D), o Preenchimento de Caixa (U), o Preenchimento de Inundação (G) e o Seletor de Azulejos (I).
Às vezes, você também pode querer editar a disposição dos blocos na própria paleta. Logo abaixo da barra de ferramentas, você verá um botão Editar. Se você clicar nele, você entrará no modo de edição de paleta, durante o qual as ferramentas afetarão a própria Paleta de Blocos. Não se esqueça de sair deste modo depois de fazer as alterações desejadas.
Em alguns casos, você pode ver uma situação em que blocos de tipos diferentes não estão sendo classificados corretamente, apesar de estarem no mesmo Tilemap, como no exemplo abaixo:

Isso é determinado pela configuração do Modo no componente Tilemap Renderer. Por padrão, o Modo é definido como Chunk.
O modo Chunk é eficaz na redução do custo de desempenho do Tilemap. Em vez de renderizar cada bloco individualmente, ele os renderiza em lote de uma só vez, como um bloco grande. No entanto, há duas desvantagens principais em usá-lo. O primeiro é o fato de que ele não suporta classificação dinâmica com outros objetos 2D na cena. Isso significa que se o seu Tilemap estiver no modo Chunk, ele não poderá classificar dinamicamente atrás e na frente de outros objetos, como caracteres. Somente um ou outro será possível por vez, com base na configuração Ordem na Camada. No entanto, ele ainda é extremamente eficaz quando você deseja otimizar seu jogo e pode ser usado para renderizar em lote grandes áreas do solo.
No entanto, isso não resolve o problema de peças diferentes não serem classificadas entre si. Para renderizar em lote blocos provenientes de dois ou mais sprites diferentes (ou seja, texturas), os sprites precisam ser unificados em um único recurso do Sprite Atlas.
Para criar um Atlas de Sprites, escolha Ativos > Criar > Atlas de Sprites. Nas configurações do Sprite Atlas, você encontrará a lista de Objetos para Embalagem. Basta arrastar todos os blocos que você deseja renderizar em lote para esta lista e definir as configurações de importação corretas — geralmente equivalentes às dos seus sprites individuais.
Depois de fazer isso, os blocos serão classificados corretamente; mas eles só ficarão visíveis dessa forma no modo de reprodução ou em tempo de execução.
Por isso, é melhor definir o Modo de Renderização do Tilemap como Individual durante a edição. Ele classificará cada peça separadamente, o que significa que você as verá renderizadas corretamente mesmo fora do modo de jogo, o que é extremamente útil quando você ainda está fazendo alterações no seu nível. Depois de definir a estrutura do seu nível, você sempre pode definir o Modo de Renderização do Tilemap de volta para Chunk.

O Modo de Renderização Individual também é útil quando você deseja adicionar objetos, como árvores, adereços e terrenos elevados, que você deseja classificar dinamicamente com personagens ou entre si. Durante esta postagem do blog, continuaremos usando o Modo Individual para todos os nossos Tilemaps.

Às vezes, você pode querer usar mais de um Tilemap na mesma grade. No caso de Tilemaps isométricos e hexagonais, será útil se você quiser adicionar objetos de suporte ao nível que também se alinhem com a grade; ou se quiser adicionar tiles que pareçam mais altos que a primeira camada.
Para anexar outro Tilemap à grade, clique com o botão direito do mouse no Objeto de Jogo da Grade e crie um novo Tilemap do tipo correspondente.
Para alternar para a pintura no novo Tilemap, volte para a janela Tile Palette e altere o Tilemap ativo logo abaixo da barra de ferramentas principal.
Geralmente, há duas maneiras de adicionar terreno elevado aos seus níveis. O que você provavelmente usará depende do tipo de mapa de blocos que você escolher. Analisaremos cada um dos casos possíveis.
Além disso, preparamos um pequeno vídeo sobre o tópico, que demonstra uma dessas abordagens com um Tilemap Isométrico regular; além de adicionar áreas de colisão aos tiles. Confira se você quiser ter uma referência rápida em vídeo para ambas as coisas:
Para Tilemaps isométricos normais, você pode simplesmente criar um novo Tilemap na mesma grade e dar a ele um valor maior de Ordem na camada. Você pode então alterar a configuração de Âncora do Bloco para fazer com que a nova camada seja ancorada em um ponto mais alto na grade.
Meu Tilemap de nível térreo tinha uma Tile Anchor de (0, 0) para X e Y, respectivamente. Quero que minha nova camada pinte uma unidade acima; então mudarei o ponto de ancoragem do novo Tilemap para (1, 1). Além disso, darei a ele uma Ordem na Camada 1 — apenas uma unidade acima do meu nível base.
Agora posso alterar meu Tilemap ativo para aquele com o segundo nível de altura e pintar.

Às vezes, pode ser útil simular alturas diferentes usando o mesmo Tilemap. Para este caso, você pode usar um Tilemap Isométrico Z como Y e uma Grade.
Com um Tilemap Z como Y, o valor Z de cada bloco tem uma influência adicional na ordem de renderização dos blocos. Podemos ajustar o valor Z que os ladrilhos têm enquanto os pintamos, usando a configuração Posição Z do nosso pincel na parte inferior da Paleta de Ladrilhos (que também pode ser alterada usando as teclas de atalho '+' e '-'):

No entanto, para que nosso valor Z contribua adequadamente e para que os blocos sejam classificados corretamente, precisamos retornar ao nosso valor de Classificação por eixo personalizado e adicionar uma influência Z. O número que usamos aqui está diretamente conectado à maneira como o Unity converte posições de células em uma grade isométrica em valores do espaço mundial.
Por exemplo, uma grade com dimensões XYZ de (1, 0,5, 1) - o padrão para isométrico - terá um valor de classificação no eixo Z de -0,26. Se você estiver curioso sobre como esse número é calculado ou estiver usando uma grade com um tamanho de célula diferente, continue lendo para saber como encontrar o valor Z correto para o seu caso.
Depois de definir o valor correto de Classificação por Eixo Personalizado, você pode começar a pintar blocos com valores Z diferentes. Você também pode ajustar os incrementos nos quais o valor Z move os blocos elevados para cima ou para baixo alterando a dimensão Z da grade, definida como 1 por padrão.

Há uma fórmula geral que você pode usar para calcular o valor Z da sua classificação por eixo. Primeiro, pegue a dimensão Y da sua grade. Se você ainda não calculou sua dimensão Y, dê uma olhada na observação sobre importação de ativos no topo desta postagem do blog. Multiplique esse valor por -0,5 e subtraia mais 0,01.
Seguindo esta fórmula, uma grade que tem as dimensões (1, 0,5, 1) nos dará um valor de classificação Z de -0,26 (ponto negativo vinte e seis). Com esse valor de classificação por eixo, qualquer grade (1, 0,5, 1) terá seus blocos classificados corretamente.
Se você quiser saber mais sobre a origem desse valor e cálculo, dê uma olhada na documentação aqui. Ele explica em detalhes como os renderizadores 2D funcionam e qual método é usado ao converter células isométricas em valores de espaço mundial.
Agora que temos algumas peças colocadas mais altas que outras, podemos controlar as áreas para onde o jogador pode ir e transitar entre elas usando colisão.
Há muitas abordagens para adicionar colisões; mas no nosso caso, queremos que o jogador suba e desça ao longo do nível usando uma rampa e, portanto, não é óbvio quais objetos devem ou não ter colisões. Em vez disso, podemos definir a colisão manualmente usando um Tilemap adicional.
Neste projeto, criamos alguns sprites que correspondem às diferentes formas que usaremos para definir nossas áreas de colisão. Podemos pintar essas formas em nosso terceiro Tilemap, nas áreas que não queremos que o jogador passe. Por exemplo, queremos que o jogador consiga subir até o penhasco usando apenas a rampa, em vez de caminhar diretamente até ele.
Também podemos adicionar um Material personalizado em nosso componente Tilemap Renderer para tingir os tiles com uma cor diferente do resto do nosso nível.
Depois de posicionar nossos tiles de colisão, podemos adicionar um componente Tilemap Collider ao Tilemap de colisão. Isso gerará automaticamente colisores para cada bloco individual com base no formato do sprite.
Para melhor desempenho, também podemos adicionar um componente Composite Collider 2D e marcar Usado pelo Composite em nosso Tilemap Collider. Isso unifica todos os nossos colisores individuais em uma grande forma.

Adicionar adereços ao nível é bem simples. Você pode colocar manualmente os sprites de adereços em qualquer ponto desejado na cena ou pode anexar os adereços à Grade do Tilemap transformando-os em blocos individuais. Você pode decidir qual abordagem funciona melhor para o seu caso.
Neste projeto, colocamos manualmente algumas árvores ao redor do nível. As árvores e o personagem têm a mesma ordem em camadas, permitindo que nosso personagem classifique atrás e na frente deles dinamicamente.
Podemos definir o ponto em que o jogador pode passar pela árvore usando um colisor. Há várias maneiras de fazer isso.
A primeira, como demonstrado nos vídeos, é anexar um colisor filho ao objeto e alterar sua forma conforme necessário.
O outro método é definir uma Forma Física Personalizada para o objeto dentro do Editor de Sprites.
Para abrir o Editor de Sprites, selecione o sprite do objeto e encontre o botão Editor de Sprites no Inspetor. No menu suspenso superior esquerdo, alterne para o editor de formas físicas personalizadas. Aqui, você pode criar uma forma poligonal para definir os limites do seu colisor personalizado.
Depois de definir uma forma física, você pode anexar um componente Polygon Collider ao seu objeto, e ele corresponderá a essa forma.
Se você estiver usando seus adereços como peças em um Tilemap, você também pode usar um Grid Collider. Selecione o Tile Asset que corresponde a um tile de prop (se precisar de uma atualização sobre onde encontrá-lo, dê uma olhada na seção Fluxo de trabalho básico do Tilemap). Você poderá ver uma configuração suspensa para o Tipo de Colisor. Por padrão, ele é definido como sprite, o que significa que o colisor gerado automaticamente usará a Forma Física sobre a qual falamos anteriormente. No entanto, se você defini-lo como grade, ele sempre corresponderá exatamente ao formato da célula da grade à qual o suporte está anexado. Pode não ser a maneira mais precisa de implementar colisores, mas pode ser útil para um tipo específico de jogo.
Para usar os colisores de grade para esses blocos, selecione o Tilemap com seus adereços e adicione um componente Tilemap Collider.

Os Rule Tiles são extremamente úteis quando se trata de automatizar o fluxo de trabalho de pintura de azulejos. Um bloco de regras atua como um bloco normal, com uma lista adicional de parâmetros de blocos. Usando esses parâmetros - ou regras - o bloco pode escolher automaticamente qual sprite deve ser pintado com base nos blocos vizinhos.
As peças de regra são úteis quando você quer evitar ter que escolher manualmente peças com rotações diferentes - por exemplo, ao criar um penhasco ou uma plataforma. Eles também podem ser usados para randomizar entre diferentes variações do mesmo bloco para evitar padrões óbvios e até mesmo para criar blocos animados.
Os blocos de regras isométricas e hexagonais estão disponíveis no repositório 2D Extras do Unity no GitHub. Eles também contêm muitos outros recursos úteis para o recurso Tilemap que você pode querer explorar.
Também incluímos Rule Tiles pré-configurados para cada um dos diferentes conjuntos de tiles em nosso projeto Isometric Starter Kit . Aqui estão alguns exemplos de peças incluídas no projeto para você experimentar:





Agora que você aprendeu os detalhes dos mapas de blocos isométricos no Unity, baixe o projeto do kit inicial isométrico aqui e experimente você mesmo! Também é possível interagir com Tilemaps via script se você for um programador, então isso pode ser algo que você queira tentar também.
Por exemplo, você pode descobrir como implementar um controlador de personagem simples que funciona com o Isometric Tilemap assistindo a este vídeo:
A arte neste projeto foi criada para Unity por @castpixel e você pode ver mais do trabalho dela aqui. Se você estiver procurando por ativos 2D adicionais para experimentar usando Tilemaps, você também pode conferir a Unity Asset Store .
---
Aprenda as melhores práticas usando o Tilemap com conteúdo para iniciantes e avançados na plataforma Unity Learn Premium.
