【Unity】Ariadneで3Dダンジョンのマップを保持している仕組み

【Unity】Ariadneで3Dダンジョンのマップを保持している仕組み

todoでございます。

自分のブログなのに自分でリリースしたアセットの話をほとんどしないという開発者にあるまじき行動をしていたのでアセットについて語ります。

この記事では3DダンジョンRPGのダンジョン部分を作ることができるEditor拡張系アセットの『Ariadne – 3D Dungeon Maker』でマップを保持している仕組みについて。

 

 

Ariadne – 3D Dungeon Makerとは

『Ariadne – 3D Dungeon Maker』は私が作ったEditor拡張系、システム/テンプレートのアセットで、3DダンジョンRPGのダンジョン部分を作ることができるものです。

RPG部分(敵との戦闘など)については他のアセットもあるのでそちらと統合してもらうことを想定していて、このアセットでは3DダンジョンRPGの舞台として使う3Dダンジョンの生成や移動の制御、ダンジョン内のイベントの制御を行っています。

RPGのシステム部分は開発者のオリジナリティも発揮される部分でもあるので、現段階ではアセットに含めていませんが、いずれはそこまでカバーしてこのアセットだけでも3DダンジョンRPGのシステムを作れるようにしたいと考えています。

元々このアセットを作り始めた理由としては、3DダンジョンRPGが好きだから、というそのまんまな理由です(笑)

3DダンジョンRPGを作りたいなーと思っている人にこのアセットを使ってもらって、楽しい3DダンジョンRPGを作ってもらってそれを遊ぶという野望もあります。

どんな感じのシーンが作れるかについては、以下のページからデモシーンを遊んでみてください。

このシーンはサンプルとして同梱している素材を使っていますが、ダンジョンのパーツを切り替えることでオリジナルのダンジョンを作成できます。アセットストアにある建物の3Dモデルを使って3DダンジョンRPGの舞台を作ることもできるので、素材を手に入れればいくらでもあなたオリジナルのダンジョンを作ることができます。

 

1.5.0にバージョンアップしたテンションで書いた記事がこちら。

 

マップはこんな感じで作ります

『Ariadne – 3D Dungeon Maker』ではMapEditorというエディタを使ってマップを作っていきます。

MapEditor
MapEditor

 

このエディタで作ったマップに沿って、実行時にオブジェクトをインスタンス化します。画面右側にある地図部分では、鉛筆ツールを使ってマップに壁や他のオブジェクトを配置していくことができます。

ペイントツールで描いていくようにダンジョンのマップを作れたらいいなーという願望からこんな感じになりました。

今のところ1マスにつきひとつのマップ属性をセットするようになっていて、世界樹の迷宮や真女神転生SJのように壁が1マス使うようになっています。いずれはWizardryのようにひとつのマスにつき4方向の壁を設定するようなスタイルもできるようにしたいなと考えています。

 

マップの各マスのデータ

マップ上の各マスではマップ属性とイベントIDを保持していて、例えば宝箱のマップ属性をセットしているマスでは宝箱を開けてアイテムの数を増やす、なんて動きをつけることができます。

また、オブジェクトがどの方向を向いているのかの情報も持っていて、インスタンス化するときに方向を決めています。例えば扉を開けて入った部屋にある宝箱だったら、ちょうど主人公が入ってきた方向を向いていて欲しいのでこの機能も入っています。

マップ全体の情報は二次元配列……かと思いきや普通にC#のList形式で各マスの情報を持っています。ダンジョン内のフロアについては縦の大きさ、横の大きさを自由に変更できるようにしているため、内部でうまく計算してリストの大きさを変えられるようにしています。

どこが通れるマスで、どこが通れないマスなのかはマップ属性の定義データから判別しています。例えば壁だったら『Can Walk』のフラグを外すことで通れないマスとして判断しています。オブジェクトを生成して壁のように見えるけれど実は通れるマスなんかも作ることができますし、溶岩ドロドロのオブジェクトを床付近に配置して通ったらダメージ、みたいな感じにもできます。

マップ属性のエディタ
マップ属性のエディタ

 

3DダンジョンRPGだと地図にアイコンを表示することもあるので、uGUIのマップとして表示できる機能をつけています。ここで使うアイコンもMapEditorと共通して使えるようにするとシステム全体で一貫性が生まれて分かりやすくなるのではと考えてこのようにしてみました。

uGUIでマップを表示
uGUIでマップを表示

 

例えば上の画像であれば画面右上のマップに扉のアイコンやメッセンジャーのアイコンが表示されています。壁のアイコンについてはMapEditorで表示するようにしていますが、uGUIのマップでは塗り潰した色で表示しています。この辺りもマップ属性の定義で設定できるようにしています。

 

移動できるかどうかの判定

ダンジョン内での移動については専用のコントローラを作っています。このコントローラの中で、主人公オブジェクトの前方のマスが進入可能なマスかどうかを確認するようにしています。

主人公オブジェクトの向きについては東西南北を表すEnumを定義しています。今どの位置にいるか、どの方向を向いているのかをstaticなクラスで保持していて、この値を使って前方のマスがどこかを特定して『Can Walk』のフラグを確認しています。

Ariadneでは2次元の地図上でどの位置にいるかをVector2Intを使って表現しています。例えば以下の画像だったら、青色のアイコンで表示している下り階段は(15, 15)の位置にあり、上の宝箱は(10, 13)の位置にあります。基準は地図の左下になっています。

地図上の位置
地図上の位置

 

地図上の位置からUnityにおけるシーン内の位置に変換して移動させるようにしています。このあたりは任意のパーツを使ってサイズを基準として、位置を計算しています。3DダンジョンRPGの場合は主観のようにカメラを動かすことが多いので、Ariadneでもそれにならって主人公オブジェクトに含まれるカメラが移動するようになっています。

 

データのほとんどはScriptableObject

Ariadneで使っているデータのほとんどはUnityの機能であるScriptableObjectを使っています。ScriptableObjectについては以下の記事もご覧あれ。

マップ属性などの定義データもScriptableObjectとして保持しているので、使うユーザーさん側で自由に追加できるようになっています。恥ずかしい話ですが以前のバージョンではマップ属性の定義をスクリプト内で追加する仕様になっていたので柔軟性という意味ではよろしくない実装になっていました。

しかしバージョン1.5.0からはスクリプトをいじる部分はかなり減らせました。アイテムの定義の部分だけはゲームごとに求められるフィールドが違うのでシステム側ではIDと名前のフィールドしか用意していませんが、partialなクラスにしたことで別のスクリプトファイルを作ってフィールドを足していけるようになっています。

ScriptableObjectを使えばデータ構造などもある程度柔軟に持てるので便利です。この辺りは苦しみながら実装した甲斐があった部分です。

 

まとめ

このページでは3DダンジョンRPGのダンジョン部分を作ることができるEditor拡張系アセットの『Ariadne – 3D Dungeon Maker』について、マップの情報を保持している仕組みについて紹介しました。

仕組み半分、苦労話半分みたいな感じでしたが、自分が作った成果物について語ろうとすると考えが整理されていいですね。

こんな感じのAriadne、良かったらデモシーンを遊んでみてください。

 

     

ゲーム開発の攻略チャートを作りました!

CTA-IMAGE

「ゲームを作ってみたいけど、何から手を付けていいか分からない!」


そんなお悩みをお持ちの方向けに、todoがアプリをリリースした経験を中心に、ゲーム作りの手順や考慮すべき点をまとめたe-bookを作成しました。ゲーム作りはそれ自体がゲームのように楽しいプロセスなので、「攻略チャート」と名付けています。


ゲームを作り始めた時にぶつかる壁である「何をしたら良いのか分からない」という悩みを吹き飛ばしましょう!