ActionStreetMapを使って自分の住んでいる街で戦う
ActionStreetMapのデモを改造して、好きな街で戦えるようにした。
改造の手順を簡単にまとめておく。
環境は以下の通り。
- Windows 7 Service Pack 1
- Unity 4.6.0f3
マップ
好きな街の3Dモデルを生成する。手順は以下のエントリーで書いた通り。
ActionStreetMapを使って自分の住んでいる街をUnityで再現する
プレイヤーと弾
デモのプロジェクトはサードパーソンビューで戦車が操作できるようになっている。ここでは、ファーストパーソンビューで移動や攻撃ができるように変えていく。
プロジェクトにはすでにFirst Person Controller
が読み込まれているので、プレイヤーをあらわすオブジェクトとしてシーンに配置する。
シーンにあるPlayerTank
を参考に、プレイヤーオブジェクトに必要なコンポーネントを追加する。具体的には、ActionStreetMapのデモのエントリポイントとしてActionStreetMapBehavior
を追加する。
次に、攻撃の仕組みを実装する。デモのプロジェクトはマウスクリックで戦車から弾が撃てるようになっているので、これを再利用する。射撃のコードはPlayerTankController
を参考にする。弾はPrefabのBullet
を使う。プレイヤーオブジェクトには弾の発生起点としてSpawnPoint
オブジェクトを追加する。
何もない空間から弾が発生するのは味気ないので、プレイヤーオブジェクトには銃の3Dモデルを追加する。以下のアセットを使った。
Asset Store - Modern Weapons Pack
敵とAI
敵の3Dモデルを用意し、アニメーションとAIを設定する。
3Dモデルは以下のアセットを使った。アニメーションも付属している。
Mecanimでアニメーションの設定をする。デフォルトではアニメーションタイプがLegacyになっているため、Mecanimで使えない。Mecanimで使えるように、Assets\FT_CaveWorm\FBX\CaveWorm_anim
を選択し、RigメニューのAnimation TypeをGenericに変えてApplyする。
Mecanimで使う場合、FT_CaveWormに付属しているIdle
やWalk
はそのままではループしない。ループ用のモーションを作るためそれぞれを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で再現する
ActionStreetMapはOpenStreetMapの地理データを使って街の3Dモデルを動的に生成するライブラリ。これを使えば好きな街をUnityで再現できる。手元でうまく動いたので、具体的な手順について書き残しておく。
環境は以下の通り。Javaはsplitterの実行に必要。
- Windows 7 Service Pack 1
- Unity 4.6.0
- Java 1.8
表示したい地域を決める
表示したい地域の緯度と経度を調べておく。今回は東京スカイツリーの周辺を表示する。
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ファイルぐらいになると思います.
Unityに取り込む
今回は、提供されているデモのデータを置き換えて街を表示する。以下のリポジトリからプロジェクトをダウンロードして展開する。
https://github.com/ActionStreetMap/demo
Assets\TopDown.unity
を実行してUnityを起動する。
まず、地域のデータを取り込む。pbfファイルとareas.list
をAssets\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
に設定されている緯度と経度を書き換える。ここで指定した位置がプレイヤーの出現ポイントになる。
アプリを実行する
そびえ立つ東京スカイツリーが見える。
見下ろすとこんな様子。