ActionStreetMapを使って自分の住んでいる街で戦う

ActionStreetMapのデモを改造して、好きな街で戦えるようにした。

改造の手順を簡単にまとめておく。

環境は以下の通り。

マップ

好きな街の3Dモデルを生成する。手順は以下のエントリーで書いた通り。

ActionStreetMapを使って自分の住んでいる街をUnityで再現する

プレイヤーと弾

デモのプロジェクトはサードパーソンビューで戦車が操作できるようになっている。ここでは、ファーストパーソンビューで移動や攻撃ができるように変えていく。

プロジェクトにはすでにFirst Person Controllerが読み込まれているので、プレイヤーをあらわすオブジェクトとしてシーンに配置する。

シーンにあるPlayerTankを参考に、プレイヤーオブジェクトに必要なコンポーネントを追加する。具体的には、ActionStreetMapのデモのエントリポイントとしてActionStreetMapBehaviorを追加する。

次に、攻撃の仕組みを実装する。デモのプロジェクトはマウスクリックで戦車から弾が撃てるようになっているので、これを再利用する。射撃のコードはPlayerTankControllerを参考にする。弾はPrefabのBulletを使う。プレイヤーオブジェクトには弾の発生起点としてSpawnPointオブジェクトを追加する。

何もない空間から弾が発生するのは味気ないので、プレイヤーオブジェクトには銃の3Dモデルを追加する。以下のアセットを使った。

Asset Store - Modern Weapons Pack

敵とAI

敵の3Dモデルを用意し、アニメーションとAIを設定する。

3Dモデルは以下のアセットを使った。アニメーションも付属している。

Asset Store - FT_CaveWorm

Mecanimでアニメーションの設定をする。デフォルトではアニメーションタイプがLegacyになっているため、Mecanimで使えない。Mecanimで使えるように、Assets\FT_CaveWorm\FBX\CaveWorm_animを選択し、RigメニューのAnimation TypeをGenericに変えてApplyする。

Mecanimで使う場合、FT_CaveWormに付属しているIdleWalkはそのままではループしない。ループ用のモーションを作るためそれぞれをDuplicateし、Loop Timeにチェックを入れる。

Animator Controllerを作成してモーションと遷移条件を設定し、敵オブジェクトに追加する。元からついているAnimationは削除する。

AIにはUnitySteerを使う。UnitySteerは追跡や群れによる行動を簡単に実装できるライブラリ。ドキュメントが少ないが、サンプルプロジェクトが参考になる。Raderを使う場合には、Layers Checkedが適切に設定されていることを確認する。

敵オブジェクトにアニメーションとAIが設定できたらPrefab化し、スポーン用のオブジェクトを作成する。

建物の破壊

デモのプロジェクトには建物を破壊するためのスクリプトDestroyableObjectが含まれている。DestroyableObjectは街の3Dモデルが生成されるとき建物オブジェクトに対して自動的に追加されるが、建物のMesh Colliderとの階層がずれていてうまく動かない。

場当たり的ではあるが、デモのソースコードに手を入れて修正する。

--- a/Assets/Scripts/Character/DemoBootstrapper.cs
+++ b/Assets/Scripts/Character/DemoBootstrapper.cs
@@ -26,7 +26,7 @@ namespace Assets.Scripts.Character
             // TODO add ability to register object without this trick
             _solidModelBehavior = new CompositeModelBehaviour("solid", new Type[]
             {
-                typeof (DestroyableObject),
+                typeof (MyCityBuilding),
                 typeof (LocationInfoHolder),
             });
using UnityEngine;
using System.Collections;
using Assets.Scripts.Map;

public class MyCityBuilding : MonoBehaviour
{

    void Start()
    {
        foreach (Transform child in transform)
        {
            child.gameObject.AddComponent<DestroyableObject>();
        }
    }

}

雰囲気を出すため、SkyboxとAmbient Light, Fogを設定する。Skyboxには以下のアセットを使った。

Asset Store - Skybox Volume 2 (Nebula)

実行

東京スカイツリーをバックにモンスターと戦えるようになった。

ActionStreetMapを使って自分の住んでいる街をUnityで再現する

ActionStreetMapOpenStreetMapの地理データを使って街の3Dモデルを動的に生成するライブラリ。これを使えば好きな街をUnityで再現できる。手元でうまく動いたので、具体的な手順について書き残しておく。

環境は以下の通り。Javaはsplitterの実行に必要。

表示したい地域を決める

表示したい地域の緯度と経度を調べておく。今回は東京スカイツリーの周辺を表示する。

35.710063, 139.8107

OpenStreetMapのデータを手に入れる

OpenStreetMap Data Extractsから表示したい地域を含むpbfファイルをダウンロードする。日本はAsiaに含まれている。asia-latest.osm.pbfのファイルサイズは3GBくらいだった。

表示したい地域のデータを手に入れる

まず、ダウンロードしたpbfファイルを分割する。pbfファイルの分割にはsplitterを使う。splitterはActionStreetMapに同梱されている。ファイルの分割にはCPU Intel Core2 Duo E8400 3GHz, RAM 8GBのマシンで2時間くらいかかった。生成されたファイルの合計サイズは6GBくらいだった。

osm_splitter.bat asia-latest.osm.pbf asia

次に、緯度と経度を頼りに、生成されたareas.listの中から表示したい地域を含むデータのidを見つける。東京スカイツリーは以下のidに含まれていた。このidに対応するデータのファイルは00003373.osm.pbfになる。

00003373: 1662976,6514688 to 1665024,6516736
#       : 35.683594,139.790039 to 35.727539,139.833984

なお、idに対応する緯度と経度はsplitterを実行した環境によって異なる場合がある。

標高データを手に入れる

以下のWebサイトから標高データをダウンロードする。日本はEurasiaディレクトリの中にある。

http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/

ファイル名の規則は以下の通り。東京スカイツリーN35E139.hgt.zipに含まれている。

ファイル名の規則

N35E139.hgt の場合

  • 左下(南西)の隅が,北緯35度 東経139度
  • 北緯35~36度,東経139~140度の範囲を含む

となります.日本全域をカバーしようとすると,全部で270ファイルぐらいになると思います.

SRTM3データから標高を読む

Unityに取り込む

今回は、提供されているデモのデータを置き換えて街を表示する。以下のリポジトリからプロジェクトをダウンロードして展開する。

https://github.com/ActionStreetMap/demo

Assets\TopDown.unityを実行してUnityを起動する。

まず、地域のデータを取り込む。pbfファイルとareas.listAssets\Resources\Maps\osmの中に置く。このとき、areas.listから不要なidを削除しておくとアプリの起動が早くなる。デモにはすでにberlinのデータが置かれているので、その隣に以下の構成でファイルを置いた。berlinは削除しなくても問題ない。

tokyoskytree/
├── 00003373.osm.pbf
└── areas.list

次に、標高データを取り込む。hgtファイルをAssets\Resources\Maps\elevationの中に置く。元から入っているN52E013.hgtは削除しなくても問題ない。

最後に、設定ファイルを編集する。Assets\Resources\Config\settings.jsonを開いて、positionに設定されている緯度と経度を書き換える。ここで指定した位置がプレイヤーの出現ポイントになる。

アプリを実行する

そびえ立つ東京スカイツリーが見える。

f:id:lanius:20141127194314p:plain

見下ろすとこんな様子。

f:id:lanius:20141127194307p:plain