PLATEAU の都市モデルを使ったユースケースでは、都市の様々なシミュレーション、まちづくりのための環境、ゲームなどが多く見られます。
こういったユースケースでは、都市モデルの景観を再現するために、人や物、そして環境を整えて様々な視点からデジタル都市を再現することが求められます。
このチュートリアルでは、PLATEAU SDK for Unityと PLATEAU SDK Toolkit for Unity を用いて、PLATEAU を使って都市を再現し、様々な視点で確認することが出来るアプリケーションを開発します。
● Unity Version 2021.3.27F1(LTS) 以降とVisual Studio
● PLATEAU SDK for Unity
● PLATEAU SDK toolkit for Unity
(1) Rendering Toolkit : 都市環境の再現
(2) Sandbox Tookit :人や車、街路樹などのオブジェクトを配置し動かす。
Unityの開発環境を整えます。
PLATEAU SDK for Unity をダウンロードしておきます。(第2章【2】参照)
PLATEAU SDK Toolkit for Unity をダウンロードしておきます。(第3章【1】参照)
Unity Hub からプロジェクトを作成します。Unity Version 2021.3.27F1(LTS) 以降の環境で、3D(URP) を選択してプロジェクトを作成します。
作成されたプロジェクトに、PLATEAU SDK for Unity を導入します。 https://project-plateau.github.io/PLATEAU-SDK-for-Unity/manual/Installation.html
PLATEAU SDKを使って、3D都市モデルをインポートします。 具体的な手順はこちらのマニュアルをご参照ください。
マウスの右クリック&ドラッグで視点方向を、キーボードのASDWQE キーで前後左右、そして上下方向の移動する機能を実装します。
Hierarchy パネルから MainCameraを選択します。Inspector パネルで、Add Conponet を押して、CameraController と入力し、そのまま NewScript を選択、続けてCreate and Add を選択してスクリプトを作成します。
Camera Controller が追加されたら、CameraController 名部分をダブルクリックしてコード作成に入ります。
下のようにコードを実装します。
public class CameraContoller : MonoBehaviour
{
//回転方向の速度
[SerializeField] float m_Sensitivity = 2.0f;
//カメラの角度保存用
float m_RotationX = 0.0f;
float m_RotationY = 0.0f;
// Start is called before the first frame update
void Start()
{
//カメラの初期角度を取得
m_RotationX = transform.eulerAngles.y;
m_RotationY = transform.eulerAngles.x;
}
// Update is called once per frame
void Update()
{
//右クリックが押されてドラッグしているときだけ視点方向を
if (Input.GetMouseButton(1))
{
//マウスドラッグの移動量から回転方向の移動量を算出して追加
m_RotationX += Input.GetAxis("Mouse X") * m_Sensitivity;
m_RotationY -= Input.GetAxis("Mouse Y") * m_Sensitivity;
//上下の角度は水平から下方向垂直近くまでに制限
m_RotationY = Mathf.Clamp(m_RotationY, 0f, 80f);
//カメラの角度としてセット
transform.rotation = Quaternion.Euler(m_RotationY, m_RotationX, 0);
}
}
}
さらに、以下のようなコードを追加すると、カーソルキーでの移動もできるようになります。(ASDW か カーソルキーで移動し、左Shift キーを押すと速く移動できる)
public class CameraContoller : MonoBehaviour
{
//回転方向の速度
[SerializeField] float m_Sensitivity = 2.0f;
[SerializeField] float m_MoveSpeed = 100.0f;
:
void Update()
{
:
//カメラの角度としてセット
transform.rotation = Quaternion.Euler(m_RotationY, m_RotationX, 0);
}
//キー入力(ASDW/カーソルキー)でカメラを移動する
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector3 movement =
new Vector3(horizontalInput, 0f, verticalInput) * m_MoveSpeed * Time.deltaTime;
if (Input.GetKey(KeyCode.LeftShift))
movement *= 3.0f;
transform.Translate(movement);
// キーによる上下移動
if (Input.GetKey(KeyCode.Q))
transform.Translate(Vector3.down * m_MoveSpeed * Time.deltaTime);
else if (Input.GetKey(KeyCode.E))
transform.Translate(Vector3.up * m_MoveSpeed * Time.deltaTime);
}
また、以下のスクリプトを追加することで、QEキーで上下移動をすることも出来ます。
void Update()
{
:
transform.Translate(movement);
// キーによる上下移動
if (Input.GetKey(KeyCode.Q))
transform.Translate(Vector3.down * m_MoveSpeed * Time.deltaTime);
else if (Input.GetKey(KeyCode.E))
transform.Translate(Vector3.up * m_MoveSpeed * Time.deltaTime);
}
実行したときのカメラの初期位置を見やすい位置に設定します。
また、Unity のScene View で見やすい場所に移動したら、Hierarchy から Main Camera を選択して、「Control(Command) + Shift + F」を押します。こうすることで現在の位置をカメラの初期位置とすることが出来ます。
PLATEAU の読み込みが終わったら、アプリを実行します。(右クリック&ドラッグで視点移動、ASDWキーで移動)
作成されたプロジェクトに、PLATEAU SDK Toolkit for Unity を導入します。サンプルも併せて導入します。
こちらからダウンロードしてください。
Rendering Toolkit のパネルを表示します(PLATEAU - PLATEAU Toolkit - Rendering Toolkit)
環境要素ボタンを押します。(モバイル用のパーティクルシステムに付いての確認は「はい」で対応)天気と時間をコントロールする環境システムが表示されます。
「Time of Day」のスライダーを操作して、時間変化を確認してみましょう。
実行して「Snow」や「Rain」「Cloudy」のスライダーを操作して、天気が変わるか確認してみましょう。
現状では、夜の窓明かりがないので、窓明かりのテクスチャを追加します。
Scene View の右下のボタンを使って、一旦Sceneを保存しておきましょう。
Scene View で都市を選択したら、Rendering Toolkit パネルで「テクスチャ生成」を押して実行します。(選択する範囲が広いと処理に時間がかかります)
もし GameViewの画面が真っ白になってしまった場合は、Project パネル内の Assets / Settings / URP-HighFidelity-Renderer を選択して、Rendering - Rendering Path を Forward から Deferrd に変更すると正しい表示になります。
Rendering Toolkit パネルの 環境システムの設定で Time of Day を夜に変更すると、窓明かりが点灯します。
雪の量をコントロールするスライダーを画面に作成して、操作ができるようにします。はじめにUIの要素をセットします。
スライダーを画面に追加しますが、スライダーを配置するエリアの背景画像を追加します。背景画像はこちらを使用します。
Project のAsset フォルダ内にImageフォルダを追加します。(Asset – Create – Folder で Imageに名前を変更)このフォルダ内に上記画像をダウンロードしてドロップします。
追加した画像を選択して、Inspector の Texture Type をDefaultからSprite(2D and UI) に変更します。こうすることで、UI上で画像を使用することが出来るようになります。
続けてスライダーを画面上に配置し、操作したら雪の量が変わるように実装します。
- Canvasを追加します。(GameObject - UI - Canvas)
- Hierarchy パネルに Canvas が追加されたら、選択し、さらにPanelを追加します。(GameObject - UI - Panel)
- Panel の位置とサイズを設定します。(Bottom/Left, PosX, PosY, Width, Height, Pivot X,Y)
- さらにPanelの背景画像を設定します。(Image Source Image を Frame に)
さらにPanelの配下に、Slider を追加します(GameObject - UI - Slider)。CloudSlider に名称を変更して、位置とサイズを設定します。
スライダーを操作したら、Rendering Toolkit の環境(Hierarchy の Environment )を変更するためのスクリプトを実装します。
他のUIを追加したときのことも考慮して、今回は Canvas にWeatherTimerController スクリプトを追加します。
以下のスクリプトを実装します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using PlateauToolkit.Rendering;
public class WeatherTimeContoller : MonoBehaviour
{
[SerializeField] Slider m_CloudSlider;
EnvironmentController m_EnvironmentController;
void Awake()
{
// Rendering Toolkit の環境コントローラを取得
m_EnvironmentController = FindObjectOfType<EnvironmentController>();
if (m_EnvironmentController == null)
return;
}
public void RainValueChanged()
{
m_EnvironmentController.m_Rain = m_RainSlider.value; ;
}
Rendering Toolkit の環境コントローラーを取得し、CloudValueChanged関数を呼び出すことで、スライダーの値を環境コントローラーの雲の量の値にセットします。スクリプトを保存します。
Canvas の Wather Time Contoller に Cloud Sliderの項目が追加されたので、右側の◎ をおして、CloudSlider を選択して追加します。
あとは、Slider の操作を行ったら、実装した CloudValueChanged の関数を呼ぶ設定を実装します。
Cloud Slider を選択し、Inspector の Slider コンポーネントの一番下、OnValueChanged の欄で +タブを押します。
ここで、Canvas を選択して、左下の欄にドラッグ&ドロップして、右上ドロップダウンボックスを開いて、WeatherTimerController - CloudValueChangedを選択します。
これで、Slider を移動すると、Canvas に追加した WeatherTimerController の CloudValueChanged関数が呼ばれ、Slider の値が、Rendering Toolkit の Cloud の値に適応され雲の量を調整できるようになります。
実行して、スライダーを動かすと雲の量を調整できるようになります。
同じようにして、SnowSlider と RainSlider も実装してみましょう。
- Slider を追加して、パネルの中に配置
- WeatherTimerController に変数と、処理用の関数を追加
- 各スライダーのOnValueChanged イベントで追加した関数を実行するように設定。
public class WeatherTimeContoller : MonoBehaviour
{
[SerializeField] Slider m_SnowSlider;
[SerializeField] Slider m_CloudSlider;
[SerializeField] Slider m_RainSlider;
EnvironmentController m_EnvironmentController;
:
public void SnowValueChanged()
{
m_EnvironmentController.m_Snow = m_SnowSlider.value; ;
}
public void RainValueChanged()
{
m_EnvironmentController.m_Rain = m_RainSlider.value; ;
}
public void CloudValueChanged()
{
m_EnvironmentController.m_Cloud = m_CloudSlider.value; ;
}
}
続けて時間変化のためのスライダーを追加し実装します。
まずはCanvas の中に Panel を追加します。(Middle/Right, PoxX, PosY, Width, Height)また背景を半透明の黒に変更します。Image - Color - 0,0,0,192 に設定します。
さらに、Panel内にSlider を追加し、TimeSlider と名前を変更します。
位置とサイズを設定して(middle/Center , Pox X, Pox Y, Width, Height ) また、縦型のスライダーにするために、Slider コンポーネントの、Direction を Top To Bottom に変更します。
WeatherTimerController に時間コントロール用のスクリプトを追加します。
public class WeatherTimeContoller : MonoBehaviour
{
[SerializeField] Slider m_SnowSlider;
[SerializeField] Slider m_TimeSlider;
:
public void SnowValueChanged()
{
m_EnvironmentController.m_Snow = m_SnowSlider.value; ;
}
:
public void TimeSliderValueChanged()
{
m_EnvironmentController.m_TimeOfDay = m_TimeSlider.value;
}
}
スクリプトを保存し、Canvasに設定されているの Weather Time Contoller コンポーネントの追加されたTime Slider の項目に TimeSliderを追加設定します。
あとは Timer Slider の OnValueChanged に、WeatherTimerController のTimeSlideValuesChangedの関数を呼ぶように設定します。
実行すると、タイムスライダーを動かして、時間変化を確認することが出来ます。
上空から地上を表示する定点カメラを追加します。
- Cameraオブジェクトを追加します。(GameObject - Camera)
- シーンビューで定点カメラの画角になるように、視点を移動します。
続けてカメラ切り替えのためのボタンを追加します。
まずはCanvas の中に Panel を追加します。(Middle/Right, PoxX, PosY, Width, Height)また背景を半透明の黒に変更します。Image - Color - 0,0,0,192 に設定 します。
続けて、パネルの中にボタンを追加します。GameObject - UI - Button(Text Mesh Pro)を選択してください。
なお、Text Mesh Pro を含む場合、TMPフォルダーの設定などのダイアログが表示されいますので、指示に従ってTextMsh Proの導入を進めます。
ボタンの名称をHomeButton にして、位置設定を Top/Center にして各パラメーターをセットします。
さらに、Hirarchy の中の追加したボタン(HomeButton)の中にある Text(TMP)のText を Button から Home に変更します。
同じようにPanel の下にボタンを追加し、SkyCamera と名前を変更して、更にテキストも Sky Camera とします。
ボタンを押して視点を切り替える機能を実装します。
Unity でカメラが複数ある場合、Camera コンポーネント内の Priority の大きいものが優先されます。
MainCamera はデフォルトで -1になっており、追加したCameraは0になっているため、追加したSkyCamera の映像が映ります。
もしくは表示したいCamera オブジェクト以外のCameraを全て Disable することでカメラを切り替えることが出来ます。
カメラを切り替えるためのスクリプトを追加します。カメラのボタンを配置した Panel に CameraSelector のコンポーネントを新規で追加します。
WeatherTimerController と同じように、関数を呼ぶことでカメラを切り替えます。起動時はMainCamera を表示するように指定します。
public class CameraSelector : MonoBehaviour
{
//回転方向の速度
[SerializeField] Camera m_HomeCamera;
[SerializeField] Camera m_SkyCamera;
private void Start()
{
SelectHomeCamera();
}
public void SelectHomeCamera()
{
DisableAllCamera();
m_HomeCamera.enabled = true;
}
public void SelectSkyCamera()
{
DisableAllCamera();
m_SkyCamera.enabled = true;
}
private void DisableAllCamera()
{
m_HomeCamera.enabled = false;
m_SkyCamera.enabled = false;
}
}
スクリプトを記述したら、保存して、Inspector で HomeCamera に MainCamera を、Sky Camera に 追加したCamera をセットしましょう。
最後に、ボタンを押したらカメラ切替用の関数を呼ぶように、ボタンのOnClickイベントに設定します。
起動時は MainCamera を使用するので、Camera は Disable にしておきます。
以上の設定により、ボタンでカメラを切り替えることが出来るようになります。
なお、キーやマウスを使った視点移動はMainCameraにのみ実装しているため、Sky Camera では視点を移動することは出来ません。
しかし天気や時間の設定は、シーン全体に対して行っているので、どちらのカメラに対しても影響します。
Plateau の都市に Sandbox Toolkit を使って人や車を配置して動かしてみます。
Sandbox Toolkit のパネルを表示します。(PLATEAU - PLATEAU Toolkit - Sandbox Toolkit )
Sandbox Toolkit を使って PLATEAU の都市に、用意された3Dオブジェクトを配置することが出来ます。配置の方法は2つ用意されています。
一つはCollider がある3Dモデル上に直接配置する方法。もう一つがトラック(移動用のパス)を作成して、トラックに配置する方法です。トラックに配置すると配置されたオブジェクトは自動的にトラック場を移動します。
まずは直接配置してみましょう。一番右のアイコンを選択します。
表示されるアイテムをScene View に直接ドラッグ&ドロップしての配置が出来ます。
また、同じオブジェクトを簡単に配置する事ができるのが、ブラシです。
ここでは例として植え込みを配置してみましょう。はじめに、配置ツールを起動します。
配置ツールパネルがScene View に表示されるので、配置方法をブラシに変更します。
植え込みのオブジェクトを選んだら、道路に線を書くように、マウスでドラッグします。
ドラッグ操作に合わせて植え込みが生成されます。生成する幅や配置数は PLATEAU 配置ツール上で設定できます。終わったら配置ツールは終了しておきましょう。
続けてトラックを作成して、その上を人が歩いたり、車が走ったりする設定をします。
まずはトラックを作るので、Sandbox Toolkit パネルの左端のボタン「トラック」を選択します。
「新しいトラックを作成」を選択して、Scene View の道路の上に、トラックのための点を打っていきトラックを作成します。
元の点に戻ってくると閉じた周回路となります。トラックが出来たら、エスケープキーかエンターキーを押すとトラックが完成します。
車道を走る車用のトラックと、建物付近を歩く歩行者用のトラックを作成します。
パスを作成する際は上空からの視点で、さらにGizmo を使ってのパースのない平行投影にすることで、地図に描く様にトラックを作成しやすくなります。
作成したトラックの上に車両が走行する設定をします。
Sandbox Toolkit で車両ボタンを選択します。
配置ツールを起動します。PLATEAU の配置位置は「トラックに沿って配置」を選択し、配置方法は「クリック」を選択します。
Sandbox Toolkit パネルから1車選んでパス上の置きたいところでクリックして配置します。連続で何台も配置することが出来ます。
同じ様に、建物付近に作成したトラック上にアバターパネルの人をクリックして配置していきます。
配置が終わったら「配置ツールを終了」して配置を完了させます。アプリを実行すると、人や車が動いていることがわかります。
Sandbox Toolkitを使って、車視点への切り替えを実装します。
Sandbox Toolkit には配置した人や車視点の表示に切り替えることが出来ます。これを実現するのが、Sandbox Toolkit のカメラマネージャーです。
Sandbox Toolkit のパネルを表示して、「カメラマネージャーを作成」をクリックして、カメラマネージャーを作成します。
やることはこれだけです。あとは、実行画面で人や車をタップすると、そのオブジェクトの視点表示に切り替わります。オブジェクト視点での表示中は、以下の操作ができます。
- 「1」キー押下 カメラを一人称視点に変更する
- 「2」キー押下 カメラを三人称視点に変更する
- 「3」キー押下 カメラを三人称中心視点に変更する
- 「0」キー押下 カメラインタラクションモードを終了する
この切り替え機能も、ボタンで操作できるようにしましょう。
まずは機能を実装します。CameraSelector に機能を追加します。
はじめに、Sandbox のUsing を追加して、PlateauSandboxCameraManager を取得するための変数を追加します。先程追加したカメラマネージャーを取得するための変数です。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PlateauToolkit.Sandbox;
public class CameraSelector : MonoBehaviour
{
//回転方向の速度
[SerializeField] Camera m_HomeCamera;
[SerializeField] Camera m_SkyCamera;
[SerializeField] PlateauSandboxCameraManager m_CameraManager;
}
続けて、視点切り替えをするためのスクリプトを記述します。
現在の視点のモードはカメラマネージャーの CurrentCameraMode で取得でき、SwitchCameraで切り替えることが出来ます。
public class CameraSelector : MonoBehaviour
{
:
public void ChangeCameraMode()
{
if( m_CameraManager.CurrentCameraMode == PlateauSandboxCameraMode.FirstPersonView )
m_CameraManager.SwitchCamera(PlateauSandboxCameraMode.ThirdPersonView);
else if (m_CameraManager.CurrentCameraMode == PlateauSandboxCameraMode.ThirdPersonView)
m_CameraManager.SwitchCamera(PlateauSandboxCameraMode.ThirdPersonOrbit);
else if (m_CameraManager.CurrentCameraMode == PlateauSandboxCameraMode.ThirdPersonOrbit)
m_CameraManager.SwitchCamera(PlateauSandboxCameraMode.FirstPersonView);
}
}
あとは、追加したCameraManager の変数に、PlateauSandboxCameraManager のオブジェクトを Hierarchy からドラッグ&ドロップして設定します。
UIを追加します。カメラ切り替えのボタンのパネルにもう一つボタンを追加して、ViewModeButton とします。配置設定をして、Text も ViewMode に変更します。
ボタンを追加したら、OnClick イベントで、先程スクリプトを追加した、ChangeCameraMode を呼び出す設定を行います。
人のアセットは、デフォルトで視点切り替え機能が無効になっています。
そのため、Hierarchy パネルで追加した人のオブジェクトをまとめて選択して、Plateau Sandbox Avatar コンポーネントの IsCameraViewAvailable にチェックを入れて下さい。