地形標高

地形標高を使うと、Maps SDK for Unity で作成したゲームに、スタイルを完全に設定できる 3 次元の地形を追加できます。Google Earth の標高データを使用すると、ゲーム内の地形をリアルに表現できます。現実世界の特定の場所にある丘や谷などの地形を表示することで、プレイヤーは周りの状況や自分がどこにいるのかを簡単に理解できます。

たとえば、次の画像はグランド キャニオンの地形標高レンダリングを示しています。この画像は、斜面に岩石や草のテクスチャを組み合わせた比較的シンプルなスタイルですが、より複雑なスタイル設定も可能です。

グランドキャニオンの地形標高の画像

地形標高は Unity Terrain エンジンと統合されているため、地形は Unity Terrain タイルとして生成されます。既存の地図対象物は地形に合わせて自動的に調整されます。Terrain Layers を使用すると、地形のスタイルを思いどおり管理したり、カスタム メソッドを定義して、地形のプロパティに基づいてレイヤを組み合わせたりすることができます。これは Unity の地形描画ツールと似ていますが、ランタイム時に適用できる点で異なります。 地形メッシュに精通している必要はありません。

地形タイルが作成されると、その都度 Maps SDK for Unity のイベント システムからゲームに通知が届きます。必要に応じて、地形生成パイプラインに追加のロジックを統合できます。

Maps SDK for Unity には、Terrian Layers を使用して地形標高のスタイルを設定する方法を示すサンプルシーンが用意されています。このシーンは Unity の [Assets] > [GoogleMaps] > [Examples] フォルダ内の [Project] ペインにあります。シーンには、「Terrain Example Script」と呼ばれる GameObject が含まれています。これには、C# スクリプト コンポーネント TerrainExample.cs が含まれます。

サンプルシーンについて詳しくは、Maps SDK for Unity のサンプルシーンをご覧ください。

地形標高を有効にする

Awake() が呼び出される前に Maps SDK for Unity マップサービス コンポーネントを使用して地形標高を有効にします。

マップサービス コンポーネントを使用して地形標高を有効にするには:

  1. Unity Inspector でマップサービスのスクリプト コンポーネントを開きます。

  2. [Map Feature Options] > [Terrain] の [Enable Terrain] チェックボックスをオンにします。

地形パラメータを設定する

地形標高を初期化する場合は、MapsService コンポーネントに次のパラメータを設定します。

TerrainMeshMetersPerPoint

生成された Unity Terrain タイルの目標解像度(ポイントあたりのメートル単位)で、デフォルト値は 1 です。

各地形タイルの実際の解像度は、TerrainMeshMetersPerPoint に指定した値と異なる場合があります。Unity Terrain タイルのハイトマップの解像度は、2 の累乗に 1 を加えた値にする必要があります。Maps SDK for Unity では、この要件を満たすために、指定された値に最も近い 2 の累乗に 1 を加えた値に丸められます。

Mixed Zoom コンポーネントで使用すると、ズームレベルが下がるたびに TerrainMeshMetersPerPoint の値は自動的に 2 倍になります。

AltitudePrecision

0.01(cm レベルの精度)~10,000(10 km レベルの精度)のメートル単位で表示される地形標高の垂直精度で、デフォルト値は 0.01 です。

地形表面の描画

Unity の Terrain エンジンは、アルファマップのコレクションに応じて一連の地形レイヤを合成することで地形表面をレンダリングします。各地形レイヤには、関連するテクスチャ(ディフューズ、法線など)があります。地形レイヤは複数の地形タイルによって共有される場合があります。

地形タイルには、地形レイヤごとに 1 つのアルファマップがあり、これがタイルの表面上の任意の地点でレイヤのブレンド ウェイトを制御します。任意の地点でのレイヤ全体のウエイトは合計で 1 になります。地形レイヤのテクスチャは地形表面全体でタイル状に並べられます。一方、アルファマップは、各タイルの表面全体を一度に覆うようにスケーリングされます。

パフォーマンス上の理由から、アルファマップはプログラムで生成する必要があります。色分けされた地図対象物を含む対象物マスク画像からサンプリングするシェーダー プログラムを実行します。対象物マスクは、AlphaMapsNeedPaint イベントの引数に含まれ、各マテリアルの通常のスタイル設定の一環として提供されるマテリアルに応じて色分けされます。統一色とともに適切な照明のないマテリアルを使用して、各対象物に色を付けます。リージョンやセグメントなどの基本地図対象物については、マテリアルで適切な基本地図互換シェーダーを使用してください。

デフォルトでは、どの対象物も対象物マスクにレンダリングされません。対象物を対象物マスクにレンダリングするには、スタイル設定の [GameObjectLayer] フィールドを、TerrainStyle オブジェクトにレンダリングする地形に指定した同じレイヤーに設定します。対象物間の地面のギャップを覆うためにグラウンド プレーン オブジェクトを使用する場合は、レイヤをレンダリングする地形にも配置して適切なマテリアルを割り当て、対象物マスクのギャップを回避する必要があります。

対象物マスクは、正投影法を使用してシーンの関連エリアに地形描画レイヤをレンダリングすることによって描画されます。適切に色分けされたゲーム オブジェクトでエリア全体を覆っていない場合は、基になる skybox が対象物マスクに表示されます。Maps SDK for Unity では、対象物マスクを描画する前に、関係するすべての地図対象物ゲーム オブジェクトが作成されますが、グラウンド プレーン オブジェクトを配置するかどうかは任意です。Maps SDK for Unity で提供されるサンプルでは、適切なグラウンド プレーン オブジェクトがすでに配置されています。

アルファマップの描画自体は、AlphaMapsNeedPaint イベントのハンドラ内で指定されたコルーチンで実行されます。このコルーチンの内容は、ご希望の地形表面の外観とアプローチによって異なります。ただし、コルーチンを返す前に、地形タイルのアルファマップを設定する必要があります。これらは、ARGB 制御テクスチャに 4 つのグループでパックされ、各チャンネルは特定のレイヤのアルファマップを表します。これらの制御テクスチャへの書き込みに使用される手法は、ご使用の Unity のバージョンによって異なります。たとえば、Unity 2019.2 以降では、TerrainData.CopyActiveRenderTextureToTexture を使用します。Maps SDK for Unity で配布される地形のサンプルには、Unity のサポートされているバージョンの推奨手法が示されています。

描画コルーチンは、返される前にキャンセルされる可能性があるため、AlphaMapsNeedPaintArgs によって提供されるデリゲートを使用してファイナライザを登録し、コルーチン内で使用するように作成された一時リソース(一時レンダリング テクスチャなど)をクリーンアップする必要があります。

詳しくは、パッケージされているサンプルをご覧ください。

構造物の配置調整

地形標高が有効になると、建物やランドマークなどの構造物が地形に対して垂直になるように配置されます。

押し出し成形される構造物は、地形と構造物の底面との間に隙間ができないように、構造物の基礎面と交差する最低高度に配置されます。これにより、建物の残り部分全体は現状を保ちつつ、各押し出し部分は細長く伸び、屋根が地面に接触することを防ぎます。

モデル化された建造物は、配置に関してのみ上記のプロセスが行われ、建造物のモデルに変更が加えられることはありません。モデル化された建造物は任意の形状であるため、フットプリントは建造物の最下点の交点によって定義されます。

Unity との連携

親と変形の仕組み

Maps SDK for Unity によって生成された GameObject は、デフォルトで、MapsService コンポーネント(地図アンカー)を含む GameObject 変形の親になります。Terrain 以外のすべての GameObject は、地図アンカーの変形に正しく準じます。

Unity は、Terrain オブジェクトの回転とスケーリングの変形に対応していません。そのため、Maps SDK for Unity で生成された Terrain GameObject は回転やスケーリングができず、こうした種類の変形が適用された親の GameObject に準じることはできません。Terrain GameObject が「静的」になっていない場合、変換に対応します。

そのため、Maps SDK for Unity は Terrain と関係するオブジェクト変形に対応していません。変形しようとすると、通常とは異なるまたは予期しない動作が発生する可能性があります。

デバイス上のレンダリング

Unity の Terrain システムは、デバイス上のレンダリングに特定のアセットを使用します。これらは、編集時に Terrain がシーンに追加されると自動的に含まれます。Maps SDK for Unity のようにランタイム時にのみ使用する場合、これらのアセットを明示的に含める必要があります。これらのアセットがないと、Terrain が正しくレンダリングされないか、まったくレンダリングされない可能性があります。

Unity の推奨されるアプローチでは、次の手順でこれらのアセットを含めることがすすめられています。

  1. Terrain GameObject をシーンの任意の場所を追加します。

  2. Inspector のコンポーネントの設定で、GameObject の Terrain コンポーネントの Draw Instanced を有効にします。

これにより、必要なすべてのアセットに依存関係が自動的に追加され、Unity バージョン間での変更の影響を受けにくくなります。この Terrain GameObject を非表示にするには、Inspector 内でその名前の横にあるチェックボックスをオフにします。このアプローチは、バンドルされた Terrain のサンプルシーンで示されています。

Terrain のサンプルシーンに示されている地形アセット。