見出し画像

【Unity】3Dローグライクゲームの作り方〜Step12-9〜

前回の記事はこちら
前回はダンジョンの自動生成を改良しました。

キャラクターID

今回は最初にキャラクターのIDを列挙定数化する所から始めたいと思います。
まずEActorスクリプトを作成し、以下のように列挙定数を定義して下さい。

public enum EActor
{
   PLAYER = 0,
   SLIME = 1
}

このID名は適宜書き換えましょう。
これができたら、Paramsクラスのidパラメーターの型をEActorに変更して下さい。
次にActorParamsControllerクラスとEnemyOperationクラスのこの部分を変更します。

// ActorParamsControllerクラス
public void Damaged(int str)
{
   /+   省略   */
   if (parameter.id == EActor.PLAYER) Message.Add(1, actorName, d.ToString());
   else Message.Add(2, actorName, d.ToString());
   /+   省略   */
}

// EnemyOperationクラス
private EDir GetPlayerDirection(ActorMovement actorMovement)
{
   /+   省略   */
   foreach (EDir d in System.Enum.GetValues(typeof(EDir)))
   {
       /+   省略   */
       if (actor == null) continue;
       EActor id = actor.GetComponent<ActorParamsController>().parameter.id;
       if (id == EActor.PLAYER) return d;
   }
   return EDir.Pause;
}

次にExcelActorDataクラスの内部クラスであるActorDataクラスのidパラメーターの型をEActorに変えます。
最後にExcelActorDataファイルのIDをEActorの定数に置き換えて下さい。

マップデータの敵の配置名をキャラクターID名に変える

キャラクターIDを作成したので、マップデータの方もそれに合わせて変更しようと思います。
まずマップファイルを開いてこのように設定し直して下さい。

スクリーンショット 2020-06-05 23.08.44

次にFieldクラスにパラメーターを追加し、SetObjectメソッドを以下のように変更します。

// パラメーターを追加
public ExcelActorData actorDatabase;

// メソッドを変更
public void SetObject(string name, string type, int xgrid, int zgrid)
{
   switch (type)
   {
       case "Stairs":
           /*   省略   */
       case "Enemy":
           EActor actorId;
           if (!System.Enum.TryParse(name, out actorId)) return;
           ExcelActorData.ActorData actorData = actorDatabase.Data.Find(n => n.id == actorId);
           if (actorData == null) break;
           GameObject enemyObj = (GameObject)Resources.Load("Prefabs/" + actorData.prefab);
           GameObject enemy = Instantiate(enemyObj, enemies.transform);
           enemy.GetComponent<ActorMovement>().SetPosition(xgrid, zgrid);
           enemy.GetComponent<EnemyOperation>().target = playerMovement;
           break;
       case "Item":
           /*   省略   */
   }
}

テストしてみます。前と同じく敵が表示されたらOKです。

敵の出現テーブル

それでは敵の出現テーブルを作成していきます。
まず新たにデータファイル(XLSXファイル)を作成します。そして、シート名を「EnemyAppear」にし、階数に応じた敵のデータテーブルを定義しましょう。
(といっても恐らく今の所1種類しか敵はいないと思いますが)
筆者は以下のようになりました。

スクリーンショット 2020-06-08 17.45.51

左から順に、階数、敵の最小数、敵の最大数、出現する敵のID、その敵の最小レベル、最大レベル、出現する確率......となっております。

アイテムの出現テーブル

次にアイテムの出現テーブルをファイルに定義したいと思います。先ほど敵の出現テーブルを書いたものと同じファイルに新たなシートを作成し、名前を「ItemAppear」にしましょう。ここに出現テーブルを書いていきます。
筆者は以下のようになりました。​

スクリーンショット 2020-06-08 9.00.40

左から、アイテムID、そのアイテムが出現し始める階層、そのアイテムが出現し終わる階層、出現確率、店の商品限定(フィールドに落ちていない)かどうか......を表しています。

出現データテーブルファイルのインポート

全て終わったら、名前を「ExcelAppearData」にして、XLSX形式で保存しましょう。
これをいつも通りAssets/Resources/Datasフォルダにインポートして、ExcelAssetScriptを作成します。
するとこのようなスクリプトが作成されたはずです。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExcelAsset]
public class ExcelAppearData : ScriptableObject
{
	//public List<EntityType> EnemyAppear; // Replace 'EntityType' to an actual type that is serializable.
	//public List<EntityType> ItemAppear; // Replace 'EntityType' to an actual type that is serializable.
}

これを以下のように書き換えて下さい。

using System.Collections.Generic;
using UnityEngine;

[ExcelAsset]
public class ExcelAppearData : ScriptableObject
{
   public List<EnemyAppearData> EnemyAppear;
   public List<ItemAppearData> ItemAppear;

   [System.Serializable]
   public class EnemyAppearData
   {
       public int floor;
       public EActor id1;
       public int lvmin1;
       public int lvmax1;
       public int rate1;
   }

   [System.Serializable]
   public class ItemAppearData
   {
       public EItem id;
       public int start;
       public int end;
       public int rate;
       public bool shoponly;
   }
}

ビルドして、ExcelAppearDataファイルを再インポートします。

といった所で、今回は終了致します。
次回、アイテムを出現テーブルに沿ってランダムに配置していきます。
本ステップも長くなりそうな感じですが、なるべく15ステップを超えないように頑張りますので、これからもよろしくお願い申し上げます。

この記事が気に入ったらサポートをしてみませんか?