フリーのUnityアセットを使って道路自動生成ツールを作成してみた

#概要
フリーのUnityアセットを利用して，道路を自動生成するツール作成してみましたので，その内容を紹介します．

フリーのUnityアセットでは，様々な道路パーツがあります．本ツールでは，道路パーツを組み合わせて，様々な走行環境を構築することを目指しています．

* 2021/09/20
  * 道路パーツをUnity UI上で作成できるようにしました．以下の記事を参照ください．
     * https://qiita.com/kanetugu2018/items/e2ed0c4d055d0b91ea22
* 2021/10/17
  * Unityアプリとしてビルドできるようにしました．

#前提とする環境
##Unity
本ツールは，Unityを前提としています．
バージョンは，2021.1.16f 以降を想定しています．

##道路パーツ
道路のフリーのUnityアセットとして，今回は以下を利用しています．

https://assetstore.unity.com/packages/3d/environments/urban/city-voxel-pack-136141

#インストール手順
## 道路生成ツール用 Unity パッケージのダウンロード
以下のサイトから道路生成ツール用のファイルをダウンロードしてください．

https://github.com/toppers/hakoniwa-Unity-Package/releases/tag/road-v1.2.0

ダウンロード対象ファイルは以下の通りです．

* hakoniwa-road-creator.unitypackage
* road_map.json
* road_parts_type.json

## Unityパッケージのインポート
新規Unityプロジェクトを作成し，`hakoniwa-road-creator.unitypackage`をインポートします．

インポート成功すると，以下のように，`Scenes`フォルダ配下に，`RoadCreator`というシーンが現れますので，それをダブルクリックしましょう．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/36c4c6b9-c93b-82d1-5b02-d4bd08b291d7.png)

## 道路パーツのインストール
Webブラウザで，以下のサイトにアクセスしてください．

https://assetstore.unity.com/packages/3d/environments/urban/city-voxel-pack-136141

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/4da8d4e3-5630-5a7a-8637-c4440a0abf9c.png)

上記の`Open in Unity`をクリックしましょう．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/27b8ce34-4b2e-4893-6697-bf75f989344f.png)

上図の`import`ボタンをクリックして，Unityアセットをインストールします．
成功すると，下図のように，`CityVoxelPack`というフォルダが作成されます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/d960c264-488f-5d34-eff1-8f566e52b8c9.png)

インポートした`CityVoxelPack`を，以下のように `Resources`フォルダへ移動してください．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/8f67d5ec-e443-23a7-4ef4-1ac299bac2e4.png)


## 道路パーツの微調整
インストールした道路パーツですが，道路自動生成するには，若干，位置の微調整が必要となります．

微調整が必要となるパーツは以下のものです(対象パーツを利用しない場合は対応不要です)．

* CityVoxelPack/Assets/roads/medium/Prefabs
  * road2/road2
     * 微調整内容：x=-2.5, z=2.5
* CityVoxelPack/Assets/roads/tall/Prefabs
  * road12
     * 微調整内容：x=-2.0, z=2.0
  * road12bis
     * 微調整内容：x=-2.0, z=2.0
  * road12bisbis
     * 微調整内容：x=2.0, z=2.0

以下，road2の設定例です．画面右の`Transform/Position`の`x`と`z`の位置を変更します．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/20ed2729-76c7-8e79-4e54-7fc636006a59.png)

これで準備完了です．

#利用手順
##道路パーツのコンフィグファイルの配置
まずは，作成したUnityプロジェクト直下に，さきほどダウンロードした以下の２ファイルを配置します．

* road_map.json
* road_parts_type.json

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/a3c1d335-773a-df2d-aead-be1a4d8c9aab.png)

##道路生成する
Unityの`Window`メニューから，道路生成用のメニューをクリックしてください．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/5433c6bc-1ec7-1619-a910-c19cccf32d57.png)

成功すると，下図のような画面がポッポアップされます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/486e02b0-6f76-018f-0aeb-dcdcbb266623.png)

なお，`Parent`は，かならず`Roads`を指定してください．

`CREATE`ボタンを押下すると，以下のように道路が現れます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/b4a836ab-c8b5-609e-d4ff-12b61c524745.png)

この道路オブジェクトは，`Hierachy`ビューの`Roads`配下に配置されています．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/71465511-9634-b504-aa19-185b454e3d60.png)

なお，各オブジェクトには，コライダが割り当てられており，このままシーンビューを見ると，コライダが割り当たっていることがわかります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/8e09009c-c9e6-3760-9ed9-17f078464e3b.png)

#各種コンフィグ情報の説明
##road_map.json
ここで作成した道路ですが，`road_map.json`でその形状を定義します．
御覧の通り，２種類の道路パーツ(road1, road2)だけで構成されています．

```json-doc
{
	"entries": [
		{
			"prefab_name": "road2",
			"rotation": 0.0,
			"connect_direction": null,
		},
		{
			"prefab_name": "road1",
			"rotation": 0.0,
			"connect_direction": "+z",
		},
		{
			"prefab_name": "road2",
			"rotation": 180.0,
			"connect_direction": "+z",
		},
		{
			"prefab_name": "road1",
			"rotation": 90.0,
			"connect_direction": "+x",
		},
		{
			"prefab_name": "road2",
			"rotation": 270.0,
			"connect_direction": "+x",
		},
		{
			"prefab_name": "road1",
			"rotation": 0.0,
			"connect_direction": "-z",
		},
		{
			"prefab_name": "road2",
			"rotation": -270.0,
			"connect_direction": "-z",
		},
		{
			"prefab_name": "road1",
			"rotation": 90.0,
			"connect_direction": "+x",
		},
		{
			"prefab_name": "road2",
			"rotation": 0.0,
			"connect_direction": "+x",
		},
		{
			"prefab_name": "road1",
			"rotation": 0.0,
			"connect_direction": "+z",
		},
		{
			"prefab_name": "road1",
			"rotation": 0.0,
			"connect_direction": "+z",
		},
		{
			"prefab_name": "road2",
			"rotation": 270.0,
			"connect_direction": "+z",
		},
		{
			"prefab_name": "road1",
			"rotation": 90.0,
			"connect_direction": "-x",
		},
		{
			"prefab_name": "road1",
			"rotation": 90.0,
			"connect_direction": "-x",
		},
		{
			"prefab_name": "road1",
			"rotation": 90.0,
			"connect_direction": "-x",
		},
		{
			"prefab_name": "road1",
			"rotation": 90.0,
			"connect_direction": "-x",
		},
		{
			"prefab_name": "road1",
			"rotation": 90.0,
			"connect_direction": "-x",
		},
		{
			"prefab_name": "road1",
			"rotation": 90.0,
			"connect_direction": "-x",
		},
		{
			"prefab_name": "road2",
			"rotation": 180.0,
			"connect_direction": "-x",
		},
		{
			"prefab_name": "road1",
			"rotation": 0.0,
			"connect_direction": "-z",
		},
		{
			"prefab_name": "road1",
			"rotation": 0.0,
			"connect_direction": "-z",
		},
		{
			"prefab_name": "road2",
			"rotation": 90.0,
			"connect_direction": "-z",
		},
		{
			"prefab_name": "road1",
			"rotation": 90.0,
			"scale": 1.285,
			"connect_direction": "+x",
		},
	]
}
```
以下，各項目の説明です．

* prefab_name
  * 今回使用したフリーのUnityアセットの道路パーツの名前です
* name
  * インスタンス化した道路パーツの名前です
  * 未設定時には自動で名前が振られます
     * 自動命名規則： {prefab_name}_{連続数値}
  * 任意の名前を付ける場合は，自動命名規則外の名前を指定してください
* rotation
  * 道路パーツの回転角度を90度単位で指定します．
* connection_direction
  * 一個前の道路パーツと接続する方向を指定します．
    * +x：+x軸方向に接続します． 
    * -x：-x軸方向に接続します． 
    * +z：+z軸方向に接続します． 
    * -z：-z軸方向に接続します． 
  * 以下の２つの指定方法で，接続するパーツを指定することもできます．
    * 指定方法１：最後に追加したprefab_name
      * +x/road2
      * 補足：交差点の道路パーツから複数のパーツを接続する場合は，この方法が有効です．
    * 指定方法２：道路パーツに名前を付けた場合のname(例：junction1)
      * 設定例：+x/junction1
      * 補足：指定方法１では最後のprefab_nameしか対応できないので，うまく指定できないケースが考えられます．その場合はこの方法で対応します
* scale
  * 道路パーツのスケールを指定します．
  * 未指定の場合は1.0倍です．
* repeat_num
  * 連続して同じ道路パーツを接続する場合は本項目で連続数を指定できます．
  * 未設定時は，連続数＝１とみなします．

##road_parts_type.json
今回使用したフリーのUnityアセットの道路パーツの定義体です．
道路パーツを増やす場合や，異なるUnityアセットを利用する場合はこの定義体をアップデートすれば拡張できるようになってます．

以下，定義例です(複数の道路パーツ定義できますので，entriesの配列として指定します)．

|パーツ名|形状|補足|
|---|---|---|
|(座標)|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/7e7fcfe1-fc14-ba7c-83ba-931fea36d84e.png)|-|
|road1|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/d36d9ffc-e1b5-6fe9-de2d-36b0ca40a46a.png)|x軸方向には他パーツは接続できない|
|road2|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244147/c035302c-ac99-f9fd-4c7e-ae9e53471c0c.png)|+xと-z方向には他パーツは接続できない|

```json
{
	"entries": [
		{
			"prefab_path": "Assets/CityVoxelPack/Assets/roads/medium/Prefabs",
			"name": "road1",
			"size_x": 21.0,
			"size_z": 39.0,
			"shift_size": [
				{
					"_comment": "+z:0",
					"can_locate": true,
					"x": 0.0,
					"z": 19.5,
				},
				{
					"_comment": "+x:90",
					"can_locate": false,
					"x": 19.5,
					"z": 0.0,
				},
				{
					"_comment": "-z:180",
					"can_locate": true,
					"x": 0,
					"z": -19.5,
				},
				{
					"_comment": "-x:270",
					"can_locate": false,
					"x": -19.5,
					"z": 0.0,
				},
			],
		},
		{
			"prefab_path": "Assets/CityVoxelPack/Assets/roads/medium/Prefabs",
			"name": "road2",
			"size_x": 37.0,
			"size_z": 37.0,
			"patch_pos": {
				"x": -2.5,
				"y": 0,
				"z": 2.5
			},
			"shift_size": [
				{
					"_comment": "+z:0",
					"can_locate": true,
					"x": 0,
					"z": 26.5,
				},
				{
					"_comment": "+x:90",
					"can_locate": false,
					"x": 26.5,
					"z": 0.0,
				},
				{
					"_comment": "-z:180",
					"can_locate": false,
					"x": 0.0,
					"z": -26.5,
				},
				{
					"_comment": "-x:270",
					"can_locate": true,
					"x": -26.5,
					"z": 0.0,
				},
			], 
		},

```

以下，定義体の設定項目の説明です．

* prefab_path
  * 利用するprefabが配置されているパスを設定します
* name
  * 利用するprefabの名前を設定します
* size_x
  * 利用するprefabのX軸方向のサイズを設定します
* size_z
  * 利用するprefabのZ軸方向のサイズを設定します
* patch_pos
  * 現時点(2021/09/06)では，未サポートですが，利用するprefabの位置調整を自動化することを目指して本項目を用意しています．
* shift_size
  * 本prefab(道路パーツ)に対して，他の道路パーツを接続する場合，そのパーツの位置をどれくらいずらす必要があるかを設定します．
  * 本prefabの接続方向は４方向ありますので，+z, +x, -z, -x の順番で指定します．
  * 以下，shift_size内部の設定項目の説明です．
    * can_locate
      * 本方向に対して接続可能かどうかを指定します．
      * 接続可能：true
      * 接続不可：false
      * 接続不可なのに，接続させようとした場合はツールはエラー終了します．
    * x
      * x 方向のシフトサイズを指定します
    * z
      * z 方向のシフトサイズを指定します