tpc17-1

TOPIC 17|PLATEAU SDKでの活用[1/2]|PLATEAU SDK for Unityを活用する

PLATEAU SDK for Unityとは、PLATEAUの豊富なデータを活用して実世界を舞台にしたアプリの開発や都市シミュレーション等を行うためのツールキットです。このトピックでは、PLATEAU SDK for Unityの利用方法を説明します。

Share

【目次】

17.1   PLATEAU SDK for Unityとは

 17.1.1  PLATEAU SDK for Unityの機能

17.2   PLATEAU SDK for Unityを使用する

 17.2.1  サンプルプロジェクトを導入する

 17.2.2  PLATEAU SDK for Unityを使用する

17.3   PLATEAU SDK for Unityでできること

 17.3.1  GISサンプルアプリ

 17.3.2  GISサンプルの3D都市モデルの変更

 17.3.3  ゲームサンプルアプリ

 17.3.4  ゲームサンプルの3D都市モデルの変更

17.1 _ PLATEAU SDK for Unityとは

図17-1

PLATEAU SDK for UnityはPLATEAUをUnityで活用するためのオープンソースのツールキットです。PLATEAU SDK for Unityを利用することで、実世界を舞台にしたゲームの開発やPLATEAUの豊富なデータを活用した都市シミュレーションを簡単に行うことができます。

PLATEAU SDK for Unityのユーザーマニュアルは、次のURLで開けます。

https://Project-PLATEAU.github.io/PLATEAU-SDK-for-Unity

ここではPLATEAU SDK for Unityを初めて利用するユーザー向けのチュートリアルとして、SDKについての解説と、SDKで何ができるのかについて知っていただくための2種類のサンプルアプリの利用方法について解説します。

17.1.1 _ PLATEAU SDK for Unityの機能

図17-2 PLATEAU SDKの概要

PLATEAU SDK for Unityでは以下の機能を提供しています。

[1]都市モデルインポート機能

都市モデルインポート機能では、PLATEAUの3D都市モデル標準製品仕様書(第2版シリーズ)に準拠しているすべての3D都市モデルデータを入力としてUnityのシーンにインポートできます。

図17-3 PLATEAU SDKでのデータの流れ

インポート処理は以下の流れで行われます。

1. ファイルの取得

必要なCityGML、コードリスト、テクスチャファイルを検索し取得します。インポート元のファイルはローカルに保存されているものだけでなく、PLATEAUが提供する配信用サーバーからインポートすることも可能です。

2. 3D都市モデルの抽出

インポート時に設定された座標範囲内の3D都市モデルを抽出します。範囲指定は座標最小値・最大値を入力とした矩形選択が可能です。

3. 平面直角座標への座標投影

CityGMLの各座標は緯度経度で保持されています。Unity内ではメートル単位で座標値を扱う必要があるため、各座標は平面直角座標に変換されます。また、この際に各地物がUnityシーン内で原点近くに表示されるようにオフセットをかけています。オフセット値は選択範囲の中心で初期設定されますが、インポート設定で自由なオフセット値に変更することも可能です。

4. CityGMLの形状データのポリゴンメッシュへの変換

CityGMLの形状データはそのままの形式ではゲームエンジンで可視化ができないため、インポート時にポリゴンメッシュへ変換しています。変換されたポリゴンメッシュはUnityシーン内でMeshオブジェクトとして可視化されます。ポリゴンメッシュに変換する際の結合単位は主要地物単位(建物、道路等)、最小地物単位(壁面、屋根面等)、地域単位(100mx100mの範囲の地物をすべて結合)から選択することができます。

[2]都市モデル調整機能

インポート機能でシーンにインポートされた3D都市モデルの見た目の調整が行えます。具体的には、以下の設定によって各地物の表示・非表示の切り替えができます。

● LOD

● 地物タイプ

 ◯ 建築物、道路、起伏等

 ◯ 最小地物単位でインポートされている場合、壁面、屋根面等面単位での表示・非表示ができます。

【メモ】LODとは

CityGMLには、各地物について複数の形状データが格納されている場合があります。LOD0は大まかな形状で、LOD1、LOD2 と数字が上がるほど細かい形状になります。建築物の場合、LOD0 は平面、LOD1は平面に一定の高さを付けたもの、LOD2はより細かい形状です。

[3]属性情報取得機能

図17-4 CityGMLとゲームエンジンでのオブジェクトの対応

属性情報取得機能ではC#ユーザー向けのAPIを提供しています。APIを利用することでCityGMLに含まれるすべての属性情報にアクセスできます。インポートされた3D都市モデルに含まれるUnityオブジェクトの名前はCityGMLでのIDに対応しているため、各オブジェクトの名前をAPIに指定することで付随する属性情報を取得できます。属性情報取得機能の詳細についてはユーザーマニュアルの都市情報へのアクセスのページをご覧ください。

[4]都市モデルエクスポート機能

都市モデルエクスポート機能ではインポートされた3D都市モデルを3Dファイル形式でエクスポートできます。

出力設定は以下の通りです。

ファイル形式OBJ、FBX、glTFに対応しています。
テクスチャ出力するメッシュにテクスチャを含めるかどうかを選択します。
非アクティブオブジェクトを含める都市モデル調整機能で非表示に設定されたオブジェクトを含めるかどうかを選択します。
座標変換出力座標系をLocal(Unityでの座標)とPlane Cartesian(平面直角座標)から選択します。
座標軸出力されるメッシュの座標軸を設定します。

17.2 _ PLATEAU SDK for Unityを使用する

PLATEAU SDK for UnityはUnityパッケージとして提供されています。本チュートリアルではSDKのサンプルを含んだプロジェクトを使用して解説しますが、個別のプロジェクトにSDKを導入したい場合はユーザーマニュアルのインストール手順に従ってください。

17.2.1 _ サンプルプロジェクトを導入する

[1]Unityをインストールする

PLATEAU SDK for Unity は、Unityバージョン 2020.3 を想定しています。そのバージョンがインストールされていない場合は、次の手順でインストールしてください。

1. Unity Hub をこちらからインストールします。
Unity Hub とは、Unityのお好きなバージョンをインストールして起動できるソフトウェアです。

2. Unity Hubを起動し、左のサイドバーから[インストール] → 右上のボタンから[エディターをインストール]をクリックします。

図17-5 Unity HubのUnityインストール画面

3. Unity 2020.3 で始まるバージョンを選択し、[インストール]をクリックします。

図17-6 Unityバージョン選択

[2]サンプルプロジェクトを導入する

1. PLATEAU SDK for Unity SamplesのページからサンプルアプリのUnityプロジェクトをダウンロードしてzipファイルを展開します。

2. Unity Hubを開き、プロジェクト画面から[開く]を選択します。

図17-7 UnityHubからプロジェクトを開く

3. 先ほど展開したUnityプロジェクトを選択して開きます。

17.2.2 _ PLATEAU SDK for Unityを使用する

[1]データのダウンロード(ローカルのデータを利用する場合)

PLATEAUの3D都市モデルデータはポータルサイトで公開されています。ポータルサイトから地域を選び、CityGMLデータをダウンロードし、展開します。

https://www.geospatial.jp/ckan/dataset/plateau

図17-8 CityGMLのダウンロード

[2]インポート元の選択(ローカル)

ここからは、ユーザーマニュアルの都市モデルのインポートのページに沿って、展開したデータをインポートします。

Unityのメニューバーから [PLATEAU]→[PLATEAU SDK]を選択してSDK画面を開きます。上部のタブから[インポート]を選択してインポート画面を開きます。

フォルダパスには、展開したCityGMLデータの最上位フォルダ(「udx」などの1つ上の階層のフォルダ)を設定します。

図17-9 フォルダパスの設定

[3]インポート元の選択(サーバー)

ローカルのデータではなくサーバーから直接シーンに3D都市モデルをインポートしたい場合、インポート元として[サーバー]を選択します。サーバー上に存在するデータセットの一覧が表示されるので、取得したいデータセットを選択します。

図17-10 サーバーのデータセットの選択

[4]基準座標系の選択

リストのうち、データが存在する場所として近いものを選択します。基準座標系が離れすぎている場合、インポートした都市モデルに歪みが生じてしまうのでご注意ください。

図17-11 基準座標系の選択

[5]インポート範囲の選択

範囲選択ボタンを押します。現在のUnityシーンに変更がある場合、変更を保存するかどうかを尋ねるダイアログが表示されるので[Save] または[Don't Save]をクリックします。シーンビューの表示が切り替わり、範囲選択画面になります。 

図17-12 範囲選択画面

● 範囲選択画面の操作方法:

 ◯ マウスホイールを上下に回してズームアウト、ズームインします。

 ◯ マウスホイールを押し込んだままドラッグしてカメラ移動します。

 ◯ オレンジ色の球体をドラッグして範囲を選択します。

 ◯ シーンビュー左上の[決定]ボタンを押して範囲を確定します。すると元のシーンに戻ります。

● 画面の見方:

 ◯ 青色の線は利用可能な地域を示します。

 ◯ 地域ごとに利用可能なGML種別と対応LODがアイコン形式で表示されます。

 ◯ 地図は国土地理院のサーバーから自動でダウンロードして表示されます。インターネットへの接続が必要です。

[6]地物別設定

地物の種類ごとにインポートに関する設定を行います。

● インポートする

 ◯ チェックが付いている地物タイプのみインポートします。

● Mesh Collider をセットする

 ◯ チェックが付いている場合、各モデルに Mesh Collider が追加されます。

● テクスチャを含める

 ◯ テクスチャが存在する地物タイプで表示される設定項目です。

 ◯ チェックが付いていて、かつテクスチャがある場合はそれを含めてインポートします。

 ◯ 都市によってはテクスチャがない場合があり、その場合はチェックを外した時と同様に真っ白な3Dモデルが出力されます。

● LOD描画設定

 ◯ 複数のLODを利用可能な地物タイプで表示される設定項目です。

 ◯ バーの左端と右端をドラッグして、インポートするLODの範囲を指定できます。

● モデル結合

 ◯ 主要地物単位(建築物,道路等)

  モデルのメッシュは建物ごとに結合されて出力されます。建物ごとに地物データを取得したい場合はこちらを選択します。

 ◯ 最小地物単位(壁面,屋根面等)

  屋根、壁単位など非常に細かくオブジェクトを分けたい場合はこちらを選択します。

 ◯ 地域単位

  モデルのメッシュは地域ごとに結合されて出力されます。オブジェクト数を削減して軽量化できますが、建物ごとの地物データは取得不可になります。メッシュの結合はある程度の大きさの範囲ごとに行われます。

[7]インポートの実行

[モデルをインポート]ボタンを押すとインポートが開始されます。

ウィンドウを下にスクロールすると、インポート処理の進捗が表示されます(図17-13)。処理が進むと、都市のオブジェクトが順次シーンに配置されていきます。進捗表示がすべて「完了」になったらインポート終了です。

図17-13 インポート処理の進捗状況
図17-14 インポートされた3D都市モデル

配置されたゲームオブジェクト階層のトップには、PLATEAUInstancedCityModelコンポーネントがアタッチされます。このコンポーネントのインスペクタから緯度、経度などの情報を確認できます(図17-15)。

図17-15 都市モデルの緯度経度情報

【メモ】

インポート元のファイルは Assets/StreamingAssets/.PLATEAU にコピーされます。.PLATEAUフォルダは隠しフォルダである点にご注意ください。

[8]各機能へのアクセス

SDKの各機能にはSDK画面の上部タブ(図17-16)からアクセスできます。SDKの機能を利用することで、インポートした都市モデルについて表示地物の調整・メッシュファイル形式へのエクスポート・属性情報へのアクセスができます。各機能の利用方法はユーザーマニュアルを参照してください。

図17-16 SDKの機能タブ

17.3 _ PLATEAU SDK for Unityでできること

PLATEAU SDK for Unityを利用することで、PLATEAUの3D都市モデルを活用したGIS、AR/VR、ゲーム等さまざまなアプリケーションを開発できます。このトピックではサンプルを使用して、SDKを利用すると実際にどのようなアプリケーションが作れるかについて解説します。

17.3.1 _ GISサンプルアプリ

PLATEAU SDKでは、どのような属性情報にアクセスできるかについて知るためのチュートリアルとして、GISサンプルアプリを提供しています。GISサンプルアプリでは、PLATEAUの3D都市モデルのさまざまな属性情報の表示や、属性情報に応じたフィルタリング・色分けができます。GISサンプルアプリは、サンプルプロジェクトに含まれるAssets/GISSample/Scenes/GISSample.unityを開き、Playすることで実行できます(初期化処理に時間がかかることがあります)。

図17-17 GISSampleをPlayしたところ

[1]カメラ操作

カメラの移動や回転には、マウスを使います。

水平移動左ボタン+ドラッグ
回転右ボタン+ドラッグ
前後移動ホイール回転
上下左右移動中央ボタン+ドラッグ または
左ボタン+右ボタン+ドラッグ

[2]属性の確認

地物をクリックすると、その地物がハイライトされ、属性情報が可視化されます(図17-18)。

3D都市モデルに含まれる各地物(建築物、道路など)の属性情報の可視化は以下の流れで行われています。

●クリックされたゲームオブジェクトの取得

●ゲームオブジェクトに対応する地物の属性情報の取得

●属性情報のUIへの表示

クリックされたゲームオブジェクトの取得

ゲームオブジェクトの取得にはUnityのレイキャスティングという機能を使用しています。画面上をクリックした際、Camera.ScreenPointToRay関数によってカメラの原点からクリックされた地点に向けて仮想のビームが射出されて、ビームが衝突した中で最も手前にあるゲームオブジェクトが取得されます。

foreach (var hit in Physics.RaycastAll(ray))
{
    if (hit.distance <= nearestDistance)
    {
        nearestDistance = hit.distance;
        nearestTransform = hit.transform;
    }
}

ゲームオブジェクトに対応する地物の属性情報の取得

SDKでインポートされた3D都市モデルのゲームオブジェクトは[3D都市モデル]/[CityGML]/[LOD]/[地物]/[子地物]という形で階層化されています。先ほど取得された地物のゲームオブジェクト(nearestTransform)から属性情報を取得するには、まずはCityGMLの読み込みを行います。

// CityGMLオブジェクトの取得
var cityGmlObject = nearestTransform.parent.parent.name;
// 都市モデルインスタンスの生成(CityGMLの読み込み)
var cityModel = await PLATEAUCityGmlProxy.LoadAsync(cityGmlObject);

インポート設定で結合設定を主要地物単位に指定している場合子地物はすべて親の地物にマージされているため、地物のゲームオブジェクトから2つ親のゲームオブジェクトを辿ることでCityGMLのゲームオブジェクトを取得しています。さらにPLATEAUCityGmlProxy.LoadAsync関数にCityGMLのゲームオブジェクトを入力することで、与えられたCityGMLの内容を読み込んでいます。

// 都市オブジェクトインスタンスの取得
var cityObject = cityModel.GetCityObjectById(nearestTransform.name);
// 属性情報インスタンスの取得
var attributes = cityObject.AttributesMap;

地物のゲームオブジェクトの名前はCityGML内での各地物のID(識別番号)に設定されています。GetCityObjectById関数を使用して地物のIDで検索することで、都市オブジェクトインスタンスの中の対応する地物の属性情報(attributes)を取得しています。

属性情報のUIへの表示

GISSampleではUIの構築にUI Toolkitを使用しています。属性情報UIのビュー設定では、スクロールビューに2つのテキストを含んだ要素を上下に並べるように設定してあります(図17-19)。スクリプトから属性情報からすべてのキーと値を取得して、それぞれの組み合わせについてUIを追加していくことで属性情報UIを構成しています。

// スクロール画面の取得
var scrollView = attributeUi.rootVisualElement.Q<ScrollView>();

foreach (var attribute in attributes)
{
    // 属性情報のキーの取得
    var key = attribute.Key;
    // 属性情報の値を文字列として取得
    var value = attribute.Value.AsString;

    // UIに要素を追加
    var elem = new VisualElement();
    elem.AddToClassList("key-value");

    var keyLabel = new Label(key);
    keyLabel.AddToClassList("key");
    elem.Add(keyLabel);

    var valueLabel = new Label(value);
    valueLabel.AddToClassList("value");
    elem.Add(valueLabel);

    scrollView.Add(elem);
}
図17-18 属性情報の表示
図17-19 属性情報UIのビュー設定(Assets/GISSample/UI/Uxml/Attribute.uxml)

[3]属性による色分け表示

高さや、各種浸水ランクで、地物を色分けすることができます(図17-20、図17-21)。

建築物の高さ情報は[bldg:measuredheight]をキーとして属性情報から取得しています。

var measuredHeight = AttributesMap.GetValueOrNull("bldg:measuredheight")?.AsDouble;

各地物のゲームオブジェクト(featureObject)からRendererコンポーネントを取得して、すべてのマテリアルのcolor変数を変更することで地物の色の変更を行っています。

// Rendererコンポーネントの取得
featureObject.TryGetComponent<Renderer>(out var renderer);
// すべてのマテリアルの色を変更
for (int i = 0; i < renderer.materials.Length; ++i)
{
    renderer.materials[i].color = color;
}
図17-20 色分けを選択するラジオボタン
図17-21 高さで色分けしたところ

[4]フィルタリング

高さや、LODの範囲を指定し、指定された範囲内の地物だけを抽出することができます。

前述のとおりSDKでインポートされた3D都市モデルのゲームオブジェクトは[3D都市モデル]/[CityGML]/[LOD]/[地物]/[子地物]という形で階層化されています。LODのゲームオブジェクト(lodObject)の名前はLOD0〜LOD3で設定されているので、名前の4文字目をパースすることでLODの値を取得しています。

if (int.TryParse(lodObject.name.Substring(3), out var level))
{
    // level変数にLODの値が格納されています。
}

各地物の表示・非表示の切り替えはGameObject.SetActive関数を使って行っています。

// LODの範囲設定に該当する最大のLODを取得
int level = -1;
for (int i = 0; i < FeatureObjects.Length; ++i)
{
    if (FeatureObjects[i] != null && i >= parameter.MinLod && i <= parameter.MaxLod) level = i;
}

// 該当する地物を表示
if (level >= 0 && level <= 3)
{
    FeatureObjects[level].SetActive(true);
}
図17-22 フィルタリングの設定を行うスライダー
図17-23 高い建物を抽出したところ

17.3.2 _ GISサンプルの3D都市モデルの変更

3D都市モデルを、任意の地域に変更できます。

[1]3D都市モデルの削除

GISSampleシーンに配置されている3D都市モデルのオブジェクト(初期状態では「13100_tokyo23-ku_2020_citygml_3_2_op」)を削除します。

図17-24 削除するオブジェクト

[2]3D都市モデルのインポート

利用したい3D都市モデルをインポートします。インポート方法については「17.2.2 _ PLATEAU SDK for Unityの機能を使用する」を参照してください。

※地物別設定では以下の設定を行ってください。

1)[土地起伏]の[インポートする]のチェックを外す
2)[Mesh Collider をセットする]のチェックをすべて入れる

図17-25 PLATEAU SDKの地物別設定

【メモ】

土地起伏については、インポートしてもしなくても機能的には影響ありません。
Mesh Collider をセットしなかった場合は、クリックしても属性情報が表示されません。
道路など、必要なければインポートしなくても問題ありません。

[3]位置の調整

Main Cameraオブジェクトの位置を調整し、3D都市モデルがビューポートに収まるようにします。

図17-26 Main Cameraの位置調整

[4]Play

Playすると、インポートした3D都市モデルの属性の確認や色分け表示ができます。

17.3.3 _ ゲームサンプルアプリ

3D都市モデルの見栄えの調整とインタラクションの作成方法について知るためのチュートリアルとして、ゲームサンプルアプリを提供しています。ゲームサンプルアプリでは、3D都市モデル内で自動車の走行を再現できます。ゲームサンプルアプリは、サンプルプロジェクトに含まれるAssets/GameSample/Scenes/GameSample.unityを開き、Playすることで実行できます。

図17-27 GameSampleをPlayしたところ

[1]操作

自動車を動かすには、キーボードを使います。

Wアクセル
Sブレーキ/バック
A / Dハンドル操作

[2]車両アセット

車両の各ホイールには、Unityの車両用コライダー「Wheel Collider」が設定されています。3D都市モデルには通常のコライダーが設定されているため、物理エンジンに基づいて車両の地面への追従、壁への衝突等の再現が行えます。また、Wheel Colliderを操作することで物理エンジンに基づいた車両の制御も再現しています。

foreach (var wheelCollider in wheelColliders)
{
// ステアリング角度を前輪に反映
if (wheelCollider.transform.localPosition.z > 0)
{
wheelCollider.steerAngle = angle;
}

// 後輪にブレーキ反映
if (wheelCollider.transform.localPosition.z < 0)
{
wheelCollider.brakeTorque = brake;
}

// 前輪にトルク反映
if (wheelCollider.transform.localPosition.z >= 0)
{
wheelCollider.motorTorque = torque;
}
}

[3]ポストプロセスの設定

ポストプロセスはUnityで画面エフェクトをかけるための仕組みです。ポストプロセスを設定することでアプリケーションの外観を簡単に改善できます。GameSampleでは以下のエフェクトが設定されています。

Bloomブルーム効果とは、画像の明るい部分の境界から光の縁が伸びているように見える効果です。
これにより、反射光が強い部分等、画面内で特に明るい光を強調して表示できます。
Ambient Occlusionアンビエントオクルージョン効果はシーンの中で環境光にさらされていない部分を暗く表現します。
Motion Blurモーションブラー効果は、カメラの動きの方向に画面をぼかします。
車両の速度に応じてエフェクトも強くなるため、スピード感の効果を増すことができます。
Chromatic Aberrationクロマティックアベレーション効果はカメラの色収差、色ズレの表現で、オブジェクトの周りに赤の光や緑の光がぼやけて表示されます。
これにより、現実でカメラのファインダーを覗いているような表現ができます。

17.3.4 _ ゲームサンプルの3D都市モデルの変更

[1]3D都市モデルの差し替え

GISSampleと同様、GameSampleでも3D都市モデルを変更できます。

インポート済みの3D都市モデルを削除したうえで、「17.2.2 _ PLATEAU SDK for Unityの機能を使用する」に従って3D都市モデルをインポートしてください。

※地物別設定では、以下の設定を行ってください。

1)[都市計画決定情報][土地利用][災害リスク]の[インポートする]のチェックを外す

2)[Mesh Collider をセットする]のチェックをすべて入れる

図17-28 PLATEAU SDKの地物別設定

【メモ】

土地起伏をインポートしないと、道路と建物の間に隙間ができたりします。

[2]位置の調整

Carオブジェクトを自動車の初期位置にしたい場所に設定します。

図17-29 Carの位置調整

ここまでの手順だけでも機能しますが、以下の設定を行うと、道路の見映えを良くできます。

[3]土地起伏の位置調整

土地起伏のオブジェクトで道路が隠れないよう、土地起伏のオブジェクトのY座標を-0.5程度にします。
土地起伏のオブジェクトは、名前に「dem」が含まれています。

図17-30 土地起伏のオブジェクト

[4]道路のマテリアル設定

道路のオブジェクトのマテリアルに「Road」を設定します。道路のオブジェクトは、名前に「TRN」が含まれています。

図17-31 道路のマテリアルを変更したところ

[5]道路の位置調整

道路の白線がある場合、道路自体と重ならないよう、道路のY座標を-0.01程度にします。

図17-32 道路の位置を下げたところ

[6]Play

Playすると、インポートした3D都市モデルの中を自動車で走行できます。

【文】

崎山 和正(株式会社シナスタジア)