Concepts clés du SDK Maps pour Unity

Les sections suivantes décrivent les concepts essentiels pour comprendre et utiliser le SDK Maps pour Unity.

Classe et composant MapsService

La classe MapsService sert de point d'entrée pour interagir avec le SDK Maps pour Unity. Il encapsule ApiKey et expose le GameObjectManager, la fonction LoadMap, ainsi que les événements du pipeline GameObject Creation.

Pour utiliser le SDK Maps pour Unity dans votre projet Unity, vous devez ajouter le composant de script Service de carte à un GameObject vide de votre scène. Le service de cartographie ajoute automatiquement les objets GameObjects générés en tant qu'enfants de cet objet GameObject d'ancrage. Lorsque le service Maps (Script) est associé à votre GameObject de base, vous pouvez accéder à ses attributs publics dans Unity Inspector, comme indiqué ci-dessous.

Service Maps (Script)

Caractéristiques géographiques en tant que GameObjects Unity

Le SDK Maps pour Unity affiche des éléments géographiques (bâtiments, routes, plans d'eau, etc.) à partir de la base de données Google Maps, en tant que GameObjects Unity dans les jeux. Au moment de l'exécution, ils sont créés en tant qu'enfants du GameObject auquel le composant MapsService est associé. Ils portent des noms au format {MapFeatureType} ({PlaceID}).

Objets de jeu du SDK

Création d'un objet GameObject

Pendant le jeu, le SDK extrait les données géographiques de la base de données Google Maps sous la forme de tuiles de vecteur sémantique (via l'API Semantic Tiles). Il décode ces données à la volée et les transforme en GameObjects Unity. Cette approche vous permet d'accéder aux données d'éléments cartographiques (à la fois aux métadonnées et aux données de géométrie) dès que possible, afin de pouvoir personnaliser les GameObjects avant qu'ils n'atteignent la fin du pipeline.

La première chose que fait le SDK Maps pour Unity lorsqu'il reçoit des données vectorielles, c'est de construire un objet MapFeature à partir de ces données.

À une étape intermédiaire du pipeline, les objets MapFeature sont spécialisés. Autrement dit, ils deviennent des types spécifiques (par exemple, un Google.Maps.Feature.ModeledStructure). Ces objets MapFeature spécialisés contiennent les détails de la géométrie MapFeatureShape (ModeledVolume dans le cas d'un ModeledStructure). Ces détails incluent à la fois les données spécifiques à MapFeature (comme les sommets et les triangles) et les interfaces partagées permettant d'accéder aux champs communs (tels que les cadres de délimitation).

Les données géométriques sont converties en Unity Mesh et sont ajoutées au GameObject généré via MeshFilter, puis affichées avec un MeshRenderer.

Accéder au pipeline

Les MapFeature vous sont exposés via des événements qui sont déclenchés à différentes étapes du pipeline. Cela inclut les événements WillCreate, déclenchés juste avant la création de GameObject, ce qui vous permet de spécifier les options de style ou même d'annuler la création, et les événements DidCreate, déclenchés juste après la création de GameObject, ce qui vous permet d'ajouter ou de modifier le maillage terminé.

Par exemple, vous pouvez examiner ExtrudedStructures après les incendies WillCreateExtrudedStructureEvent et masquer tous les bâtiments de moins de 20 mètres (ou ignorer complètement leur création).

Types d'événements

L'espace de noms Google.Maps.Event contient une classe d'événement pour chaque type d'élément géographique.

Chacun de ces types d'événements comporte un objet d'événement de membre public WillCreate et DidCreate auquel vous pouvez vous abonner, comme illustré dans l'exemple de code suivant.

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 événements

Les événements WillCreate sont déclenchés immédiatement après la création d'un MapFeature, mais avant que le GameObject final soit généré à partir de celui-ci. Les événements WillCreate vous permettent de supprimer ou de personnaliser les GameObjects créés à partir d'un MapFeature. Les arguments d'événement WillCreate se présentent sous la forme suivante:

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;
    }
  }
}
  • Définir Cancel (hérité de CancelEventArgs) sur true supprime la création du GameObject.
  • MapObject est en lecture seule.
  • Définir Style vous permet de personnaliser l'apparence du GameObject créé.
  • La définition de Prefab remplace le GameObject qui aurait été généré, par le Prefab.

DidCreate événements

Les événements DidCreate sont déclenchés après la génération d'un GameObject, après son ajout à la scène. Ils vous avertissent lorsque la création du GameObject a réussi, ce qui vous permet d'effectuer un traitement supplémentaire. Les arguments d'événement DidCreate ont la forme suivante:

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 est en lecture seule. Sa mutation n'entraînera donc aucun changement dans la scène.
  • La modification de CreatedObject modifie le GameObject ajouté à la scène.

bâtiments

Il existe deux types de bâtiments: les bâtiments extrudés et les structures modélisées.

Bâtiments extrudés

Les bâtiments extrudés sont générés à partir d'un contour (c'est-à-dire une empreinte en 2D) et d'une hauteur. Le SDK représente la plupart des bâtiments de cette manière et les génère des trois manières suivantes:

  • Utilisation de données de hauteur réelles (lorsque ces informations sont disponibles). Il s'agit du comportement par défaut.

  • En indiquant une hauteur fixe pour tous les bâtiments, sans tenir compte de leur hauteur réelle.

  • En fournissant une hauteur de sauvegarde pour tous les bâtiments qui n'ont pas de hauteur réelle (par défaut, cette valeur est définie sur 10 mètres).

Combiner ces trois méthodes permet au SDK Maps pour Unity de créer des paysages urbains avec une variance réaliste reflétant le monde réel, avec une hauteur de bâtiment constante ou une combinaison des deux.

Structures modélisées

Les structures modélisées sont générées à l'aide de l'approche de modélisation 3D standard des triangles tessellés. Cette approche est généralement utilisée pour les bâtiments emblématiques tels que la statue de la Liberté.

La statue de la Liberté modélisée

Application des supports

Dans Unity, le processus de rendu utilise des nuanceurs, des matériaux et des textures pour ajouter du réalisme à GameObjects. Les nuanceurs définissent la façon dont les textures, les couleurs et l'éclairage sont appliqués à la géométrie affichée, les textures, les couleurs et les autres paramètres spécifiques utilisés étant stockés en tant que matériau. Vous utilisez des matériaux pour définir le rendu d'une surface, en incluant des références aux textures qu'elle utilise, aux informations de carrelage et à la couleur.

Les nuanceurs sont de petits scripts qui contiennent la logique de calcul de la couleur de chaque pixel en fonction de l'entrée d'éclairage et de la configuration matérielle. Le SDK Maps pour Unity est fourni avec un nuanceur standard pour les structures modélisées et un autre pour les fonctionnalités de carte de base. Il est également compatible avec les applications Material avancées. Les coordonnées pour le mappage UV sont calculées pour l'élément cartographique GameObjects de manière à ce que tout matériau de base puisse être appliqué. Celles-ci paraîtront raisonnables sans modification.

Pour des effets de matériaux plus avancés, le SDK Maps pour Unity fournit des données supplémentaires par sommet via des canaux UV supplémentaires, ainsi qu'un certain nombre de fonctions pratiques pour les nuanceurs cg via la bibliothèque GoogleMapsShaderLib. Cela permet, par exemple, de créer des textures de construction à neuf tranches, c'est-à-dire de découper une texture pour le toit, le sol, les coins de mur et les murs en tuiles d'un bâtiment.

Pour en savoir plus, consultez l'article Creating and Using Materials (Création et utilisation de matériaux) du manuel de l'utilisateur Unity.

Canaux UV

Les canaux UV de chaque type MapFeature contiennent des données sous la forme suivante:

ExtrudedStructure

Walls

Chaque paroi d'une ExtrudedStructure est construite sous la forme d'un quad de la forme suivante:

Walls

Les coordonnées UV des murs sont calculées par quad. Les sommets ne sont pas partagés entre les quadrants, pour permettre des normales dures entre les murs (en laissant les coins des murs apparaître sous forme d'angles durs plutôt que sous forme d'arêtes arrondies douces).

Canal 0: (x, y, largeur, hauteur)
x et y sont les coordonnées relatives à l'angle inférieur gauche de ce quad (section carrée) du mur, tandis que width et height correspondent à la largeur et à la hauteur de ce quad de mur. Cela s'applique à chaque quad qui compose la paroi.
Toiture

Les textures de toit peuvent être alignées sur l'axe ou sur la direction du ExtrudedStructure. Vous définissez ce paramètre via l'objet ExtrudedStructureStyle.

Canal 0: (x, y, largeur, hauteur)
x et y sont les coordonnées de chaque sommet, par rapport à l'angle inférieur gauche du toit (plus précisément, l'angle du cadre de délimitation du toit, aligné sur l'axe de couverture minimale). width et height définissent la taille du cadre de délimitation du toit.

Region

Canal 0: (x, y, largeur, hauteur)
x et y sont les coordonnées de chaque sommet par rapport à l'angle inférieur gauche du cadre de délimitation aligné sur l'axe pour la région. width et height définissent la taille du cadre de délimitation.

Segment

Canal 0: (x, y, largeur, longueur)
x et y sont les coordonnées de chaque sommet. Elles sont calculées comme si le segment était entièrement droit afin de permettre à l'application de texture de plier les angles. Les attributs width et length définissent les dimensions du segment.

ModeledStructure

Canal 0:
Chaque coordonnée est définie sur (0, 0, 0, 0), car il n'existe actuellement aucune implémentation de coordonnées de texture.

GoogleMapsShaderLib

Le SDK Maps pour Unity inclut une bibliothèque de nuanceurs appelée GoogleMapsShaderLib, qui vous aide à créer des nuanceurs qui fonctionnent bien avec MapFeature GameObjects. Cette bibliothèque est implémentée dans le fichier GoogleMapsShaderLib.cginc. Vous pouvez utiliser la bibliothèque en incluant l'instruction #include suivante dans la section des options CGPROGRAM de votre script de nuanceur.

CGPROGRAM
// ...
#include "/Assets/GoogleMaps/Materials/GoogleMapsShaderLib.cginc"
// ...
ENDCG

La bibliothèque de nuanceurs est intégrée au GoogleMaps.unitypackage. Après avoir importé le package, vous trouverez GoogleMapsShaderLib.cginc dans le dossier du projet /Assets/GoogleMaps/Materials/.

Neuf tranches

GoogleMapsShaderLib inclut une fonction pratique que vous pouvez utiliser dans les nuanceurs de fragments pour fournir une segmentation en neuf tranches de textures. La tranche en neuf est une technique permettant de couvrir des surfaces avec une texture, où celle-ci est divisée en neuf parties à l'aide d'une série de limites. Les zones situées entre les limites sont en mosaïque et les zones situées en dehors des limites restent fixes, comme illustré ci-dessous:

Neuf tranches

Par exemple, lorsque vous appliquez une texture à neuf tranches au mur d'un bâtiment, le haut de la texture est appliqué en haut du mur (juste sous le toit), le bas de la texture est appliqué au bas du mur (connecté au sol), les côtés de la texture sont appliqués aux bords du mur et la zone située au milieu de la texture est carrelée uniformément sur le mur.

Sur les routes (par exemple, le tracé en neuf sections), vous pouvez avoir un trottoir de largeur fixe, mais avec un nombre de voies variable en fonction de la largeur de la route.

Pour utiliser la segmentation en neuf segments, incluez GoogleMapsShaderLib.cginc dans votre nuanceur, puis appelez la fonction nineSlice. Des exemples de nuanceurs et de matériaux sont inclus dans GoogleMaps.unitypackage pour montrer comment vous pouvez utiliser la fonction nineSlice pour créer un skyscraper réaliste de taille variable, sans étirement ni déchirure.

Exemple d'emplacement de Material Design
/Assets/GoogleMaps/Examples/04_Advanced/MoreStyling/Materials/NineSlicing
Exemple d'emplacement du nuanceur
/Assets/GoogleMaps/Examples/04_Advanced/MoreStyling/Materials/NineSlicing/BuildingWall.shader

Vous pouvez utiliser le découpage à neuf tranches sur n'importe quel MapFeature, à l'exception de ModeledStructures, qui ne comporte actuellement aucune coordonnée de texture.

Le système de coordonnées

Le système de coordonnées du SDK Maps pour Unity utilise la projection Mercator Web pour effectuer la conversion entre la latitude-longitude sphérique WGS 84 et la latitude-longitude cartésienne Unity Worldspace (Vector3).

Les valeurs des vecteurs 3 sont relatives à une origine flottante, qui est généralement définie sur le point de départ de l'utilisateur. Par conséquent, vous ne devez pas conserver les valeurs Vector3 en dehors d'une session (c'est-à-dire sur votre serveur ou sur l'appareil de l'utilisateur). Nous vous recommandons de spécifier des emplacements dans le monde physique à l'aide de paires latitude-longitude.

Une origine flottante permet d'éviter les problèmes de stabilité en virgule flottante. La classe Vector3 d'Unity utilise des nombres à virgule flottante à simple précision, et la densité des nombres à virgule flottante représentables diminue à mesure que leur magnitude augmente (les nombres à virgule flottante plus grands deviennent donc moins précis). Vous pouvez mettre à jour l'origine flottante chaque fois que les utilisateurs s'éloignent suffisamment de l'origine pour que cela représente un problème. Vous pouvez définir cette valeur sur une valeur relativement faible (par exemple, 100 ou 200 mètres) ou supérieure (supérieure à 1 km) en fonction de la fréquence de mise à jour.

Unity Worldspace est ajusté à 1:1 (mètres), en fonction de la latitude du point de départ initial. Dans la projection de Mercator, l'échelle varie légèrement en fonction de la latitude. L'échelle d'Unity Wordspace divergent donc légèrement de 1:1 lorsque les utilisateurs se déplacent vers le nord et le sud. Toutefois, les utilisateurs ne sont pas censés se déplacer assez loin (ou rapidement) pour que cela soit perceptible.

Le SDK Maps pour Unity contient des fonctions de conversion permettant de convertir des données entre Google.Maps.LatLng et Unity Worldspace (Vector3), qui tiennent compte de l'origine et de l'échelle flottantes.

Erreurs de chargement

Les erreurs qui se produisent lors du chargement des données de carte à partir du réseau peuvent être gérées avec l'événement MapLoadErrorEvent. Le SDK Maps pour Unity gère lui-même la plupart des types d'erreurs si vous n'ajoutez pas de gestionnaire d'événements. Cependant, une erreur nécessite une action de la part de votre application. Ceci est spécifié par MapLoadErrorArgs.DetailedErrorCode et décrit ci-dessous.

UnsupportedClientVersion

Cette version du SDK Maps pour Unity n'est plus compatible, peut-être en combinaison avec la clé API actuelle. En règle générale, votre application doit inviter l'utilisateur à passer à une version plus récente.

Cette erreur signifie généralement que la version du SDK Maps pour Unity est trop ancienne. Dans de rares cas, nous pouvons l'utiliser si nous découvrons un problème critique avec une version du SDK Maps pour Unity ou une clé API. Nous ferons tout notre possible pour communiquer ces informations et nous assurerons que cela ne se produit pas tant qu'il n'y aura pas de version fonctionnelle de l'application à mettre à jour.

Il est recommandé de vous assurer que votre application dispose d'un chemin de mise à niveau approprié dans le cas où cette erreur se produira, ce qui permettra à vos utilisateurs de migrer vers une version plus récente de votre application avec une version du SDK compatible. Pour en savoir plus, consultez la documentation du bouton d'arrêt du client.

Problèmes connus

Les éléments cartographiques de base sont affichés dos à l'avant sans tests z, car tous les éléments de ce type sont affichés sur le même plan. Vous devez définir le z-testing sur ZTest Always (Toujours Test Z) sur tous les matériaux de remplacement que vous appliquez aux éléments cartographiques de base afin de vous assurer qu'ils s'affichent correctement.

Google a inclus un exemple de nuanceur qui résout ces problèmes dans le GoogleMaps.unitypackage. Il s'appelle "BaseMapTextured.shader et se trouve dans le dossier /Assets/GoogleMaps/Materials/. Pour l'utiliser sur un matériau, sélectionnez Google > Maps > Shaders > BaseMap Textured dans la liste déroulante du nuanceur de l'inspecteur de matériaux.

Lorsque vous appliquez un style à un objet Feature.Region ou Feature.AreaWater, vous pouvez appliquer un remplissage à l'aide d'une matière, d'une couleur personnalisée ou d'une couleur générée automatiquement choisie via l'énumération FillModeType dans l'objet de style. Les couleurs Auto sont générées en fonction de la valeur du type d'utilisation de la région.