As seções a seguir contêm descrições dos conceitos essenciais para entender e usar o SDK do Maps para Unity.
A classe e o componente MapsService
A classe MapsService
serve como ponto de entrada para interagir com o SDK do Maps para Unity.
Ela encapsula a ApiKey e expõe a função GameObjectManager e LoadMap, bem como Eventos do pipeline Criação de objeto de jogo.
Para usar o SDK do Maps para Unity no seu projeto do Unity, adicione o componente do script do serviço de mapa a um GameObject
vazio na cena. O serviço de mapas adiciona automaticamente o GameMap gerado como filhos a esse objeto. Com o serviço do Maps (Script) anexado ao seu GameObject de base, você pode acessar os atributos públicos dele no Unity Inspector, conforme mostrado aqui.
Recursos geográficos como Unity GameObjects
O SDK do Maps para Unity renderiza recursos geográficos (como construções, estradas e água) do banco de dados do Google Maps, como o GameObjects do Unity em jogos. No ambiente de execução, eles são criados como filhos do GameObject ao qual o componente MapsService está anexado e têm nomes no formato {MapFeatureType} ({PlaceID}).
Criação de GameObject
Durante o jogo, o SDK extrai dados geográficos do banco de dados do Google Maps, como blocos de vetor semântico (por meio da API Semantic Tile). Ele decodifica esses dados rapidamente, transformando-os em GameObjects do Unity. Essa abordagem permite acessar os dados de recursos do mapa (os metadados e os dados de geometria) o mais cedo possível, para que você possa personalizar os GameObjects antes que eles cheguem ao fim do pipeline.
A primeira coisa que o SDK do Maps para Unity faz quando recebe dados vetoriais é criar um objeto MapFeature
a partir deles.
Em um estágio intermediário no pipeline, os objetos MapFeature
são especializados. Ou seja, eles se tornam tipos específicos (por exemplo, um Google.Maps.Feature.ModeledStructure
). Esses objetos MapFeature
especializados contêm os detalhes de geometria MapFeatureShape
(no caso de um ModeledStructure
). Esses detalhes incluem dados específicos do MapFeature (como vértices e triângulos) e interfaces compartilhadas para acessar campos comuns (como caixas delimitadoras).ModeledVolume
Os dados de geometria são convertidos em um
Unity Mesh
e adicionados ao GameObject gerado pelo
MeshFilter
.
Em seguida, eles são exibidos com um
MeshRenderer
.
Como acessar o pipeline
MapFeature
s são expostos a você por meio de eventos que são acionados durante vários estágios do pipeline. Eles incluem
eventos WillCreate
, que são disparados pouco antes da GameObject
ser
criada, permitindo que você especifique as opções de estilo ou até mesmo cancelar
a criação, e os eventos DidCreate
, acionados logo após a criação do GameObject
,
permitindo que você adicione ou mude a malha concluída.
Por exemplo, você pode examinar ExtrudedStructures
depois do disparo do WillCreateExtrudedStructureEvent
e ocultar todos os edifícios com menos de 20 metros ou ignorar a criação deles.
Tipos de evento
O namespace Google.Maps.Event
contém uma classe de evento para cada tipo de recurso geográfico.
- Eventos de segmentos
- Eventos em regiões
- Eventos de linha de água
- Eventos da área da água
- Eventos de estruturas expandidas
- Eventos de estruturas estimadas
Cada um desses tipos de evento tem um objeto de evento de membro público WillCreate
e DidCreate
que pode ser inscrito, como demonstrado no exemplo de código a seguir.
dynamicMapsService.MapsService.Events.ExtrudedStructureEvents.DidCreate.AddListener(args => { // Apply nine-sliced walls and roof materials to this building. buildingTexturer.AssignNineSlicedMaterials(args.GameObject); // Add a border around the building base using the Building Border Builder class, // coloring it using the given border Material. Extruder.AddBuildingBorder(args.GameObject, args.MapFeature.Shape, BuildingAndRoadBorder); });
WillCreate
eventos
Os eventos WillCreate
são disparados imediatamente após a criação de um MapFeature
, mas antes que o GameObject final seja gerado a partir dele. Os eventos WillCreate
permitem suprimir ou personalizar os GameObjects criados a partir de um MapFeature
.
Os argumentos de evento WillCreate
têm o seguinte formato:
using System.ComponentModel; using Google.Maps.Decoded; using UnityEngine; namespace Google.Maps { public class WillCreateGameObjectEventArgs<T, U> : CancelEventArgs where T : IMapObject, U : IGameObjectStyle { public readonly T MapObject; public U Style; public GameObject Prefab; Public WillCreateGameObjectEventArgs(T mapObject, U defaultStyle, GameObject prefab) { MapObject = mapObject; Style = defaultStyle; Prefab = prefab; } } }
- Definir
Cancel
(herdado deCancelEventArgs
) como true suprime a criação do GameObject. MapObject
é somente leitura.- A definição de
Style
permite personalizar a aparência do GameObject criado. - Definir
Prefab
substitui o GameObject que teria sido gerado pelo prefab.
DidCreate
eventos
Eventos DidCreate
são disparados depois que um GameObject é gerado, depois de ter sido adicionado à cena. Eles notificam você quando a criação do GameObject foi
bem-sucedida, permitindo que você execute mais processamento. Os argumentos de evento DidCreate
têm o seguinte formato:
using System.ComponentModel; using Google.Maps.Decoded; using UnityEngine; namespace Google.Maps { public class DidCreateGameObjectEventArgs<T, U> : EventArgs where T : IMapObject, U : IGameObjectStyle { public readonly T MapObject; public GameObject CreatedObject; Public DidCreateGameObjectEventArgs(T mapObject, GameObject createdObject) { MapObject = mapObject; CreatedObject = createdObject; } } }
MapObject
é somente leitura. Mudá-lo não causará nenhuma mudança na cena.- A alteração de
CreatedObject
altera o GameObject adicionado à cena.
prédios
Existem dois tipos de construções: construções extrudadas e estruturas modeladas.
Edifícios extrudados
As construções extrudadas são geradas a partir de um contorno (ou seja, uma planta 2D) e de uma altura. O SDK representa a maioria dos edifícios dessa maneira e os gera das seguintes maneiras:
Usar dados de altura reais (onde essas informações estão disponíveis). Esse é o comportamento padrão.
Fornecer uma altura fixa para todos os edifícios, independentemente da altura real deles.
Fornecendo uma altura de backup para todos os edifícios que não têm uma altura real (por padrão, esse valor é definido como 10 metros).
A combinação desses três métodos permite que o SDK do Maps para Unity crie paisagens urbanas com variação realista que reflitam o mundo real, com uma altura constante de construção ou uma mistura dos dois.
Estruturas estimadas
As estruturas modeladas são geradas usando a abordagem de modelagem 3D padrão de triângulos tesselados. Essa abordagem normalmente é usada para edifícios históricos, como a Estátua da Liberdade.
Aplicando materiais
No Unity, o processo de renderização usa sombreadores, materiais e texturas para adicionar realismo a GameObjects. Os sombreadores definem como as texturas, cores e iluminação são aplicadas à geometria exibida, com as texturas, cores e outras configurações específicas usadas como material. Você usa materiais para definir como uma superfície é renderizada, incluindo referências às texturas que ela usa, à divisão de informações e à cor.
Os sombreadores são pequenos scripts que contêm a lógica para calcular a cor de cada pixel, com base na entrada de iluminação e na configuração do material. O SDK do Maps para Unity vem com um sombreador padrão para estruturas modeladas e outro para recursos de mapa básico, mas também é compatível com aplicativos avançados de material. As coordenadas para o mapeamento UV são calculadas para o GameMaps do recurso de mapa de modo que qualquer material básico possa ser aplicado e terá uma aparência razoável sem modificações.
Para efeitos de material mais avançados, o SDK do Maps para Unity fornece mais dados por vértice com canais UV extras, bem como várias funções de conveniência para sombreadores cg usando a biblioteca GoogleMapsShaderLib
.
Isso permite elementos como as texturas de construção nove fatias (link em inglês), cortando uma textura no telhado, no chão, nos cantos de uma parede e nas paredes ladrilhadas de uma construção.
Para mais informações, consulte Criar e usar materiais no Manual do usuário do Unity.
Canais UV
Os canais UV de cada tipo de MapFeature
contêm dados no seguinte formato:
ExtrudedStructure
Walls
Cada parede em um ExtrudedStructure
é construída como um quadrinho do seguinte
formato:
As coordenadas UV das paredes são calculadas por quad. Os vértices não são compartilhados entre quadrângulos, o que permite normas rígidas entre as paredes, ou seja, os cantos das paredes aparecem como ângulos rígidos, em vez de bordas arredondadas.
- Canal 0: (x, y, largura, altura)
- x e y são as coordenadas em relação ao canto inferior esquerdo desse quadril (seção quadrada) da parede, enquanto width e height são a largura e a altura desse quadrângulo da parede. Isso se aplica a todos os quadrângulos que compõem a parede.
Telhado
As texturas de telhado têm a opção de serem alinhadas aos eixos ou alinhadas à
direção de ExtrudedStructure
. Isso é definido por meio do objeto ExtrudedStructureStyle
.
- Canal 0: (x, y, largura, altura)
- x e y são as coordenadas de cada vértice em relação ao canto inferior esquerdo do telhado (especificamente, o canto da caixa delimitadora alinhada ao eixo mínimo para o telhado). width e height definem o tamanho da caixa delimitadora do teto.
Region
- Canal 0: (x, y, largura, altura)
- x e y são as coordenadas de cada vértice em relação ao canto inferior esquerdo da caixa delimitadora alinhada ao eixo para a região. width e height definem o tamanho da caixa delimitadora.
Segment
- Canal 0: (x, y, largura, comprimento)
- x e y são as coordenadas de cada vértice, calculadas como se o segmento fosse completamente reto, para permitir que a textura gire em torno dos cantos. width e length definem as dimensões do segmento.
ModeledStructure
- Canal 0:
- Cada coordenada é definida como (0, 0, 0, 0) porque atualmente não há implementação de coordenadas de textura.
GoogleMapsShaderLib
O SDK do Maps para Unity inclui uma biblioteca de sombreadores chamada GoogleMapsShaderLib para ajudar a criar sombreadores que funcionam bem com MapFeature GameObjects. A biblioteca é implementada no arquivo GoogleMapsShaderLib.cginc. Você pode usar a biblioteca incluindo a
seguinte diretiva #include
na seção de sinalizações CGPROGRAM
do script de sombreador.
CGPROGRAM // ... #include "/Assets/GoogleMaps/Materials/GoogleMapsShaderLib.cginc" // ... ENDCG
A biblioteca de sombreadores está agrupada no GoogleMaps.unitypackage. Depois de importar o pacote, você pode encontrar GoogleMapsShaderLib.cginc na pasta do projeto /Assets/GoogleMaps/Materials/.
Nove fatias
O GoogleMapsShaderLib inclui uma função de conveniência que pode ser usada em sombreadores de fragmentos para fornecer o fracionamento de nove partes de texturas. O recorte de nove partes é uma técnica para cobrir superfícies com textura, em que a textura é dividida em nove partes usando uma série de limites. As áreas entre os limites são lado a lado, e as áreas fora dos limites permanecem fixas, conforme ilustrado aqui:
Por exemplo, ao aplicar uma textura de nove fatias à parede de uma construção, a parte superior da textura é aplicada à parte superior da parede (logo abaixo do teto), a parte inferior da textura é aplicada à parte inferior da parede (conectada ao solo), os lados da textura são aplicados às bordas da parede e a área no meio da textura é dividida uniformemente na parede.
Em estradas (para outro exemplo), o compartilhamento de nove partes permite que você tenha uma calçada com largura fixa, mas com um número variável de pistas, dependendo da largura da estrada.
Você pode usar o fracionamento de nove partes incluindo GoogleMapsShaderLib.cginc em seu sombreador e chamando a função nineSlice
. Os sombreadores e materiais de amostra estão incluídos no GoogleMaps.unitypackage para demonstrar como você pode usar a função nineSlice
para criar um arranha-céu realista de tamanho variável, sem esticar ou rasgar.
Exemplo de localização de materiais
/Assets/GoogleMaps/Examples/04_Advanced/MoreStyling/Materials/NineSlicing
Exemplo de local do sombreador
/Assets/GoogleMaps/Examples/04_Advanced/MoreStyling/Materials/NineSlicing/BuildingWall.shader
Você pode usar o fracionamento de nove em qualquer MapFeature
, exceto ModeledStructures
,
que atualmente não tem coordenadas de texturização.
O sistema de coordenadas
O sistema de coordenadas do SDK do Maps para Unity usa a Projeção da Web Mercator para converter entre a latitude e longitude esférica do WGS 84 e o Unity Worldspace cartesiano (Vector3).
Os valores de Vector3 são relativos a uma origem flutuante, que normalmente é definida como o local de início do usuário. Como resultado, você não deve manter os valores do Vector3 fora de uma sessão (ou seja, no seu servidor ou no dispositivo do usuário). Recomendamos que você especifique locais físicos do mundo usando pares de latitude e longitude.
Uma origem flutuante é usada para evitar problemas de estabilidade de ponto flutuante. A classe Vector3 do Unity usa números de ponto flutuante de precisão única, e a densidade dos números de ponto flutuante representativos diminui à medida que a magnitude aumenta. Isso significa que números de ponto flutuante maiores se tornam menos precisos. É possível atualizar a origem flutuante sempre que os usuários se afastarem o suficiente da origem em que isso se torna um problema. Você pode defini-lo como um valor relativamente pequeno (por exemplo, 100 ou 200 metros) ou maior (maior que 1 km), dependendo da frequência com que você quer atualizar as coisas.
O Unity Worldspace é dimensionado para 1:1 (metros), com base na latitude da origem inicial. Na projeção Mercator, a escala varia ligeiramente de acordo com a latitude. Portanto, a escala do Unity Wordspace diverge um pouco de 1:1, já que os usuários se movem para o norte e para o sul. No entanto, não é esperado que os usuários se movam longe (ou rápido) o suficiente para que isso seja perceptível.
O SDK do Maps para Unity contém funções de conversão para a conversão entre o Google.Maps.LatLng
e o Unity Worldspace (Vector3), que consideram a origem e a escala flutuantes.
Erros de carregamento
Erros que ocorrem ao carregar dados do mapa da rede podem ser tratados com o evento MapLoadErrorEvent
. O SDK do Maps para Unity processa a maioria dos tipos de erro se você não adicionar um manipulador de eventos. No entanto, há um erro que exige que seu app realize alguma ação. Isso é especificado por
MapLoadErrorArgs.DetailedErrorCode
e descrito abaixo.
UnsupportedClientVersion
Esta versão do SDK do Maps para Unity não é mais compatível, possivelmente em combinação com a chave de API atual. Normalmente, o app precisa solicitar que o usuário atualize para uma versão mais recente.
Esse erro geralmente indica que a versão do SDK do Maps para Unity é muito antiga. Em casos raros, podemos usar isso se descobrirmos um problema crítico com uma versão do SDK do Maps para Unity ou com uma chave de API. Faremos o possível para comunicar isso e garantir que isso não aconteça até que haja uma versão em funcionamento do app disponível para atualização.
A prática recomendada é garantir que o app tenha o caminho de upgrade adequado caso esse erro ocorra. Isso permite que os usuários migrem para uma versão mais recente do app com uma versão compatível do SDK. Para mais informações, consulte a documentação chave de segurança do cliente.
Problemas conhecidos
Os recursos do mapa básico são renderizados de frente para a frente sem o teste Z, porque todos os recursos desse tipo são renderizados no mesmo plano. Defina o teste Z como ZTest Always nos materiais de substituição aplicados aos recursos do mapa básico para garantir que eles sejam renderizados corretamente.
O Google incluiu um exemplo de sombreador que resolve esses problemas no GoogleMaps.unitypackage. Ele se chama "BaseMapTextured.shader
e está localizado na pasta /Assets/GoogleMaps/Materials/
. Para
usá-lo em um material, selecione Google > Maps > Shaders >
BaseMap Textured na lista suspensa do sombreador no inspetor de material.
Ao estilizar um objeto Feature.Region
ou Feature.AreaWater
, é possível aplicar um
preenchimento usando um material, uma cor personalizada ou uma cor gerada automaticamente
escolhida usando a
enumeração FillModeType
no objeto de estilo.
As cores de Auto
são geradas com base no valor do tipo de uso da região.