[Unity] すぐに遊べるダンジョンを自動生成(Dungeon Architect & Multistory Dungeons)
有料アセットである「Dungeon Architect」(DA)と「Multistory Dungeons」(MSD)に含まれるデモを利用し、Unity(2019.4)にて自動生成の迷宮(ダンジョン)を舞台にしたあそべるゲームのプロトタイプを作成してみます。
今回のノートは、Unity アセット真夏のアドベントカレンダー 2020 Summer! 3日目 8月3日エントリー用の投稿です。
昨日の記事は石田ぎがしーさんの最高の Hierarchy Window を目指して ~QHierarchy & Hierarchy Folders~でした。
明日はゆーじさんの【DOTween】イージングの選び方ポイントを分かりやすく解説です。
1. 概要
アセットに含まれるデモシーンをロードし、セットアップして、自動生成のダンジョンを舞台にした半完成アクションシューティングゲーム(DA版 Survival Shooter(※1))で、まず遊んでみます。(全7ステップ)
そのあとは、お楽しみの改造タイムです。気になるところをリバースエンジニアリングして修正していくというスタイルを通じて、ゲーム制作に必要なアセットとUnityの使い方を遊びながら身につけていくというアプローチを提案します。
両方とも高価なアセットであり、なかなか手が出せないかもしれませんが、過去たびたびセールが行われています。それを狙ってみるのもよいかと思います。
サンプル動画は照明を調整し、プレイヤー操作・カメラ操作を改造しています。
なお、DA版 Survival Shooterには以下の特徴があります。
・美麗な立体的なダンジョンが生成される。
・スタートとゴールが離れた地点に自動的に設定される。
・通路と部屋に敵とWaypoint(※2)が自動的に設定される。
・自動的に NavMesh(※3)が設定される。
・敵キャラは簡易的なAIを搭載している。
・ミニマップがついています。個人的に感動ポイントです。
※1) DA版 Survival Shooter は、Unity Learn などにある、Survival Shooter チュートリアルのカスタマイズ版です。
※2) Waypointは経路をあらわすポイントです。敵キャラの巡回などにつかわれています。詳細は本稿の範囲外ですが、ゲーム制作に役立ちますので、このサンプルをいろいろといじってみるとよいでしょう。
※3) NavMeshは経路探索とキャラクターの移動制御のための仕組みです。
2. 今回使用するアセットの紹介
今回使い方を紹介するアセットは2種類あります。それぞれダンジョンの自動生成スクリプトと、そのもとになる地形データです。
1) ダンジョン自動生成アセット 「Dungeon Architect」
・価格:$95(2020年7月時点)
・製作者:Code Respawn
迷宮型ダンジョンに限らず、様々なステージを自動生成できるアセットです。詳細は「Unity AssetStoreまとめ」さんの記事がとても参考になります。
2) ダンジョン地形データ 「Multistory Dungeons」
・価格:$45(2020年7月時点)
・製作者:Mana Station
とてもミステリアスなダンジョンなので、ミステリアスダンジョンかと読み違えましたが、正確にはマルチストーリーダンジョンズです。詳細はまたもや「Unity AssetStoreまとめ」さんの記事がとても参考になります。
Dungeon Architect は、床や壁の定義(テーマ)を変更することで様々なダンジョンに対応します。Multistory Dungeons には、なんと、Dungeon Architect 向けのテーマが同梱されているのです。これを使わない手はありませんね。
3. セットアップ手順
1) 空の3Dプロジェクトを作成します。
名前は Random_Dungeon_Shooter とでもしておくと良いでしょう。
2) Dungeon Architect をインポートします
Asset StoreタブのMy Assetから、Dungeon Architect を[Import]します。
Import Unity Packageウィンドウが開きますので、[Import]します。
以上でDungeon Architect のインポートは完了です。
3) デモシーンをセットアップします。
UnityエディタのProject から、 Assets > DungeonArchitect_Samples > Game3D_SurvivalShooter > Scenes > CandySurvivalShooter をダブルクリック(または右クリックからOpen)します。
*いったんデモシーンを実行してみます。
Play(実行)してみると、ちょっとおかしいところはありますが、とりあえずゲームが動きます。ひととおり遊んでみてください。
Unityのチュートリアルにもある、Survival Shooter のアレンジ版です。
WASDキーで移動、マウスで向きを変え左クリックで射撃、ESCキーでポーズがかかります。
スペースキーか緑色のワープポータルに到着すると次のステージのはずですが、バグのためプレイヤーがへんなところにワープします。
次からの手順でシンプルな地形を、美麗なダンジョンに作り変えます。
ついでにバグも修正します。
4) Multistory Dungeons をインポートします。
Unityでディタの Asset StoreタブのMy Assetから、Multistory Dungeons を[Import]します。
import Unity Packageウィンドウが開きますので、「Multistory Dungeons PC Gamma 2018.4.unitypackage」(※4)のみを選択し、[Import]します。(ほかはチェックアウトします。下図参照)
※4) URPやPC Linerを使用されるかたは、選択するパッケージを変更してください。(今回はそれらの使い方は説明しません)
5) Multistory Dungeons のパッケージを展開します。
Unityエディタの Project から Assets > Multistory Dungeons > Multistory Dungeons PC Gamma 2018.4 を選択し、ダブルクリック(または右クリックからOpen)します。
Import Unity Packageウィンドウが開きますので、[Import]します。
DunGen Presets は使わないので、チェックを外してもかまいません。
以上でMultistory Dungeons のインポートは完了です。
6) デモシーンをマルチストーリーダンジョン用にカスタマイズします。
・Hierarchy > DungeonGridゲームオブジェクトの Inspector にある、Dungeon (Scropt) の Dungeon Themes を展開します。
・Dungeon Themes の Element 0に、「MultiStory_Base」テーマをセットします。
「MultiStory_Base」テーマは、UnityエディタのProject の、 Assets > Multistory Dungeons 2 > Dungeon Archtect Presets > Theme の下にあります。これをドラッグアンドドロップしてください。
DungeonGridゲームオブジェクトは、今後もよく使いますので、Inspectorをロックしておくとよいかもしれません。
*いったんデモシーンを実行してみます。
Play(実行)してみると、ちょっとおかしいところはありますが、とりあえずダンジョンの景観ががらりとかわったことがわかるでしょう。
7) おかしいところを修正していきます。
階段のずれ、敵キャラが動かないところ、ワープ後に主人公がなすすべもなく落下していくところを修正します。
a) 段差の修正
階段に移動できないほどのずれが生じています。これを修正します。
DungeonGridゲームオブジェクト の Inspector にある、Grid Dungeon Config (Script) の[Grid Cell Size Y]を 2→1 に変更します。
b) NavMeshが有効にならない原因を修正
地面と階段のNavMeshが有効になっていないため、敵が動きません。これを修正します。
① Project から Assets > Multistory Dungeons 2 > Dungeon Archtect Presets > Theme > MultiStory_Base (以降MSDテーマ)をダブルクリック(または右クリックからOpen)します。
さきほど Dungeon にアタッチしたテーマ(地形や壁を定義したもの)を編集するための「DungeonTheme編集ウィンドウ」が開きます。
② マウスのホイールとホイールプレスでの移動をつかって、以下の4点を修正します。
1) Ground > Base 01 の、Affects Navigation にチェックをいれる。
2) Ground > Base 02 の、Affects Navigation にチェックをいれる。
3) Ground > Base 03 の、Affects Navigation にチェックをいれる。
4) Stair > Stair_Pool_01 の、Affects Navigation にチェックをいれる。
※他にも壁(Wall)や手すり(Fence)など、気になったオブジェクトには後ほどチェックをいれてみるとよいでしょう。
注意) これらの操作を行うと、なぜかSceneに勝手にダンジョンが生成されます。Hierarchy の DungeonGridゲームオブジェクト にある、Dungeon (Scropt) の Destroy Dungeon でダンジョンを消しておきます。
消しておかないと、Play(実行)時、ものすごく時間がかってしまいます。
c) ステージ切替時にPlayerの座標が変更されない不具合の修正
これは、コードを直接編集します。
① Hierarchy の DungeonGridゲームオブジェクト にある、SpecialRoomFinder.cs の修正
void TeleportPlayerTo(Vector3 position)
{
var player = GameObject.FindGameObjectWithTag(GameTags.Player);
if (player != null)
{
// (1)下の行をコメントアウトします。
// player.transform.position = position;
var movement = player.GetComponent<PlayerMovement>();
if (movement != null)
{
//movement.OnTeleportered();
// (2) 上のコードを下のように修正します。
movement.OnTeleportered(position );
}
}
}
② Hierarchy の Playerゲームオブジェクト にある、PlayerMovemnt.cs の修正
// public void OnTeleportered()
// (3) 上のコードを下のように修正します。
public void OnTeleportered(Vector3 position)
{
// 下の2行を追加
character.enabled = false; // (4)追加
transform.position = position; // (5)追加
character.enabled = true;
}
おつかれさまでした!
以上で不具合の修正は終了です。まずは思う存分遊んでみてください。
WASDキーで移動、マウスで向きを変え左クリックで射撃、ESCキーでポーズがかかります。
スペースキーか緑色のワープポータルに到着すると次のステージにワープします。
4. ゲームの改造案
Unityとサンプルを理解するために、ちょっといじってみます。
1. ダンジョンをいじってみる
ダンジョンの生成パラメータは、Hierarchy の DungeonGridゲームオブジェクトにアタッチされている、GridDungeonConfig にあります。
数値を変えながら「Build Dungeon」をして確認できますが、その場合はPlay(実行)前には「Destroy Dungeon」をしておくようにしてください。
【主要パラメータ】
・Seed:ダンジョン生成のシード値です。パラメータが一緒で、Seedも一緒であれば、何度生成しても同じダンジョンが生成されます。
今回のサンプルゲームではプレイ毎に自動的に変更となります。
・NumCells(標準値100):ダンジョンの大きさです。100はゲームとしては広いほうですので、最初のほうのステージは30などにしておくとよいでしょう。(ステージクリアで変更していくパラメータ候補のひとつですね!)
・Corridor Width (標準値2):通路幅です。1にすると通路が狭くなります。
・Room Area Threshold:生成されたセルのサイズがこの値を超えると、部屋になります。それ以下の場合は通路になります。
・Room Aspect Delta:セルのアスペクト比(幅と高さの比)。この値を0に近づけると正方形の部屋になり、1に近づけると長方形になります。
・Height Variation Probability(推奨値0.2~0.4):この値を微調整することで、ダンジョン内の高低差(と階段)を増加/減少させることができます。0に近い値を設定すると高低差が減少し、1に近づくにつれて増加します。
・Max Allowed Stair Height:ダンジョンの高さが変化することができる論理階単位の数。0か1か2です。これは、ダンジョンの高さを変化させることができる高さを決定します。
最大2階分の高さを作ります。そのとき、テーマ内のStear2X が使わます。
ここを2にするときに出現する、サンプルのテーマの Steir2X は調整が必要です。この記事のいちばん最後に、修正値を記載しておきます。
・Spanning Tree Loop:スパンニングツリーのループ。ダンジョンの中にいくつのループを作りたいかを指定します。0に近い値を設定するとループが少なくなり、直線的なダンジョンになります。
1に近い値を設定すると、たくさんのループが発生し、特徴がなくなります。いくつかのループがあると自然にみえるので、0に近い値(0.2のような値)が良いでしょう。
2. 敵キャラクターをいじってみる
1) 敵キャラクターの性能を変える
Assets > DungeonArchitect_Samples > Game3D_SurvivalShooter > Prefabs にある、「ZomBear」「ZomBunny」のプレファブを修正します。
・耐久度: EnemyHealth.cs にある startingHealth
・移動速度:Nav Mesh Agent にある Speed
まずはこの2つの値を変更してみます。
基本的には、増やすと強くなります。
このプレファブには、巡回や索敵など、簡易的なAIが実装されています。解析して改造するのは楽しそうです!
2) 敵キャラクターの出現比率を変える。
GameControllerゲームオブジェクトの Level Npc Spawner の Spawn Probability(標準0.25 = 25%)を変更すると、敵キャラの出現率が変わります。
敵の出現判定は、WayPointごとに設定されています。
WayPointの多い広場には敵がたくさん出現しやすく、WayPointの少ない部屋内には敵が出現しにくくなります。
WayPointの確認は、ゲーム実行中に一時停止をかけて確認します。
Hierarchy の Waypointsゲームオブジェクトをクリックすることにより、Waypointと、経路の繋がりが表示されますので、それで確認できます。
3.ものすごく邪魔な壁をなんとかする。
DAサバイバルシューターとMSDテーマの思想の違いにより、初期設定では壁をカメラ視線が通りにくくなっています。壁が生成される向きは、MSDテーマ内で参照されるルールスクリプトにより定義されているので、これを編集します。
1) Project から Assets > Multistory Dungeons 2 > Dungeon Archtect Presets > Theme > MultiStory_Base をダブルクリック(または右クリックからOpen)します。
2) Wall から接続される左側のNoneをクリックします。
3) Inspector に MeshNode_110 の設定が表示されるので、Selection Rule にある、「NonViewBlockingSelection」をダブルクリックします。
4) スクリプトの以下の部分を編集します。
static Vector3[] validDirections = new Vector3[] {
new Vector3(1, 0, 0),
//new Vector3(0, 0, 1),
// 上の定義を下のように修正する
new Vector3(0, 0, -1),
};
5) Play(実行)前に「Destroy Dungeon」をしておきます。
これでカメラの視線と壁の生成方向が一致し、だいぶ見やすくなるはずです。
5. 将来の改造案
Survival Shooter は半完成品ですが、わりと優れいていて、まず「遊び」として成立しています。
反面、ルールはあくまで最低限しか実装されていません。
こうしたら面白くなるんじゃないかとピンとくることが思います。そのとき、改造してみることができます。
(例1) いわゆる、ふつうのゲームっぽくする
1. 武器がレーザービーム(着弾まで0秒)ではなく弾にする。
2. 弾の種類を増やす
3. 拾えるアイテムを作る
実は、これらはすでに改造した先人がいらっしゃいます。
→ 【Unity】Survival Shooter Extendedがクソ面白い件についてを参照してください。
ほかにもいろいろありますよね、気になるところ。次章を参考にして、改造チャレンジしてみてはいかがでしょうか。
6. 改造のための虎の巻
かる~く、プロジェクトのどこでなにをしているかをメモしておきます。
修正するときに参照してください。
1.「Playerゲームオブジェクト」
プレイヤーの移動などのスクリプトがアタッチされています。
プレイヤーの容姿、アニメーション、移動、ヒットポイント(および死亡 =ゲームオーバー)、攻撃について設定されています。
1) PlayerHealth.cs スクリプト
プレイヤーのヒットポイント、ゲームオーバーなど。
・TakeDamage …… プレイヤーにダメージを与える場合はこれをコールするとよいでしょう。
2) PlayerMovement.cs スクリプト
プレイヤーの移動。大改造が必要ですね!
(別途note記事を作成する予定です)
3) PlayerShooting.cs (Player > Gun > MuzzleLight)
射撃について記述されています。マウスボタンを押すと撃つというふるまいは、ここに実装されています。
2. 「Main Cameraゲームオブジェクト」
カメラは移動には追従しますが、角度は固定カメラです。
ゲーム中、カメラの角度をかえたいことが多々あると思います。
1) Camera Follow.cs スクリプト
カメラの移動。大改造が必要ですね!
(別途note記事を作成する予定です)
→作成しました! 2021/02
3. 「GameControllerゲームオブジェクト」
ゲームのレベルデザインに関わる機能です。
1) GameController
ダンジョンの生成
・CreateNewLevel……現在のダンジョンを破棄し、新しいダンジョンを作成します。このスクリプトを改造すれば、ステージ数が上がるたびにダンジョンを広くしたりなどのレベルデザインができるようになりそうです。
2) LevelNpcSpawner
敵キャラの出現。
・RebuildNPCs…現在のNPCを破棄し、Waypointにそって新しいNPCをスポーンさせます。
・spawnProbabilityの確率(デフォルトで0.25 =25%)の確率で敵が配置します。
npcTemplates[] に設定されたプレファブを設置します。デフォルトでは zomBearとZomBunnyの2種類が登録されています。Sizeを増やすことで、出現する敵キャラのバリエーションを増やすことができます。
・(GetValidPointOnNavMesh…NPCがNavMeshから外れたとことにスポーンしたときに、NavMesh内になるよう位置を調整する内部関数です)
・DestroyOldNpcs…全NPCを破棄します。
4.「DungeonGridゲームオブジェクト」
Dungeon Archtect のランダムダンジョン生成本体を含む、ダンジョン生成に関する機能です。
1) SpecialRoomFinder.cs スクリプト
スタート地点、ゴール地点を設定します。
2) WaypointGenerator.cs スクリプト
Waypointを生成します。
5.「Misc > MenuCanvasゲームオブジェクト」
Pause Manager にESCキーを押したときの処理が記述されています。
表示されるConfigウインドウはダミーです。自分で処理を作る楽しみが残されています……!
6. プレファブ
Assets > DungeonArchitect_Samples > Game3D_SurvivalShooter > Prefabs 下に、サンプルゲームのプレファブがあります。
1) LevelEndGoalプレファブ
ゴールのもやエフェクトです。ここに到着するとダンジョンが再生成となる処理は、これに実装されています。
また、スペースキーを押すとダンジョンが再生成になるのも、ここに記述されています。
2) ZomBear、ZomBunnyプレファブ
敵キャラのプレファブです。Hellphant は使用されていません!
7. MSDテーマ (MultiStory_Base)
何度かいじったMSDテーマには、ダンジョンで生成されるものが定義されています。これを編集することで、ダンジョンの景観を自分好みにすることができます。
1) 部屋の中心にオブジェクトを出現させる
部屋の中心になにかをポップさせたい場合は、Multistory_Baseテーマのなかにある「RoomCenter」を改変するのがいちばん簡単。
標準ではDungeon_PinkLightが100%配置されるようになっているので、これを置き換えてみましょう。
7. おまけ
大階段がおかしい場合は、MSDテーマ内のStare2X(Railling Stair)のパラメータを以下のように修正ください。(2個とも)
・Position X:2 Y:2 Z:2
・Rotation X:0 Y:0 Z:0
以上、おおまかに解説させていただきました。
Dungeon Architect は、他にも様々な地形アセットに対応していますし、市街地や階層型ダンジョンも生成できる、奥深いアセットです。
ぜひとも楽しみつつチャレンジしていただいて、面白い作品を作るきっかけになってもらえれば、このうえない喜びです。