前回:オートバトラー系ゲーム開発日誌 #4
作業日:2019/09/17
オレオレ実装かつコードの一部しか載せてないためなんのこっちゃって感じだと思いますが、メモ代わりだと思ってください。
駒データをExcel上から取得する
オートチェスの駒には職業や種族、攻撃力などの情報がそれぞれ必要なため、
Excel上でデータを管理し、それを取り込んで参照したいと思います。
実装イメージはこんな感じ。
駒データのxlsxからScriptableObjectへの変換は、Unity Excel Importerを使用させていただきました。
使い方は上記リンクに書かれていますが、一応自分の手順もメモしておきます。
駒データの型定義
ExcelデータをScriptableObjectに変換する際、各カラムの型(文字列型、数値型、enum型)を判別する情報が必要です。
それを定義するのがPieceDataEntityクラスです。
[Serializable]
public class PieceDataEntity
{
public string id;
public string name;
public PieceJob job;
public PieceRace race;
public int hp;
public int mana;
public int attackDamage;
public float attackSpeed;
}
中身はこんな感じ。
[Serializable]は書かないと生成されるScriptableObjectの中身が空になってしまうので必須です。
PieceJob、PieceRaceはenum型です。
public enum PieceJob
{
FIGHTER,
MAGE
}
public enum PieceRace
{
HUMAN,
ORC
}
駒データの作成
こんな感じでExcelデータを作成。一行目はPieceDataEntityで定義したフィールド名と同じにしないとダメ。
あと、シート名は後述するScriptableObject生成用のコードで使用されるので、わかり易い名前をつけておく。
ExcelフォルダをUnityシステム上で作ってこのデータを保存しました。
(PieceData.xlsx)
駒データの変換
UnityのProjectビュー上で保存したExcelファイルを右クリックし、「ExcelAssetScript」を選択。
テンプレートスクリプトの保存先を聞かれるので、Scriptフォルダ内にExcelDataフォルダを作成し、そこに保存。
ExcelDataフォルダ内のPieceData.csファイルを開き、以下の通り変更。
[ExcelAsset]
public class PieceData : ScriptableObject
{
public List<PieceDataEntity> PieceDatas; // Replace 'EntityType' to an actual type that is serializable.
}
そしてExcelファイルを保存し、閉じる。
(閉じないと僕の環境ではエラーが出ました)
その後Unityのコンパイルが走ると、Excelファイルの保存フォルダ上に
Excelファイルと同名のScriptableObjectができます。(PieceData)
シングルトンなStorageクラスを作る
上記で作ったScriptableObjectを参照するためのシングルトンなStorageクラスを作ります。
シングルトンクラス自体の実装は他サイト様で提供されている汎用的なやつを使っているので、
Unityで少しだけ高速なシングルトン(Singleton)などを参照して実装しました。
Storageクラスはこんな感じで実装。GetPieceDataEntity経由で駒データを取得します。
こうすることで、もしIDが一致しなかった場合にデフォルト値を参照することできたりエラーを出したり便利そう。
using UnityEngine;
using System.Linq;
public class PieceDataStorage : SingletonMonoBehaviour<PieceDataStorage>
{
const string DEFAULT_DATA_ID = "TEST0000";
[SerializeField]
PieceData storage;
public PieceDataEntity GetPieceData(string id)
{
var data = storage.PieceDatas.First(x => x.id == id);
// もし同一IDのデータが見つからなかったらデフォルト値のIDで再検索し、そのデータを返す.
if(data == null)
{
data = storage.PieceDatas.First(x => x.id == DEFAULT_DATA_ID);
if (data == null)
Debug.LogError("デフォルトID:" + DEFAULT_DATA_ID + " のデータが存在しません。");
else
Debug.LogWarning("ID:" + id + " のデータが存在しないため、デフォルトID:"
+ DEFAULT_DATA_ID + " のデータを使用します。");
}
return data;
}
}
特にエラーメッセージとか出さないのなら、??を使ってデフォルト値をセットする方がシンプルで良さそうです。
駒データの取得
PieceData内のidフィールドをキーにデータを取得することで、駒オブジェクトから駒データを利用します。
public class GamePiece : MonoBehaviour
{
[SerializeField]
string PieceDataId;
void Start()
{
var data = PieceDataStorage.Instance.GetPieceData(PieceDataId);
print(data.name);
}
}
仮にPieceDataIdにFIGHTER0001をセットして実行した画像は以下のとおり。
ステータスの初期値やテキストなど変動しない情報はこのExcelで管理したいと思います。