ゲームデータについて(6)テキストデータのつづき

前記事からの続きです。

ラベルのコンバータを作成

textData.xlsmのB列に記載されたラベル定義をソースコードとして出力するコンバータを作成します。
他のコンバータと同様にUnity Editor上に作りたいところですが、出力されるファイルはプロジェクトの一部になるので、出力に失敗して空ファイルになるとプロジェクトのコンパイルが通らなくなってしまいます。
それを避けるためにExcelVBAマクロでコンバータを作成します。
textData.xlsmに以下のマクロを作成します。

Sub OutputTextLabel()

  '出力先
  StrFileName = ThisWorkbook.Path + "\..\..\GameData\TextData\TextDataLabel.cs"

  'ファイルをオープン
  Dim adoStream As Object
  Set adoStream = CreateObject("ADODB.Stream")

  adoStream.Type = 2
  adoStream.Charset = "UTF-8"
  adoStream.Open

  '書き込み処理
  'ヘッダ書き込み
  adoStream.WriteText "//-----------------------------------------------------------------------------", 1
  adoStream.WriteText "//  note : このファイルはマクロから出力されています。直接編集しないでください。", 1
  adoStream.WriteText "//-----------------------------------------------------------------------------", 1
  adoStream.WriteText "using UnityEngine;" & Chr(13) & Chr(10), 1
  adoStream.WriteText "public enum TEXT_LABEL", 1
  adoStream.WriteText "{", 1

  'ラベル書き込み準備
  Dim strLabel As String
  Dim strIndent As String
  strIndent = Chr(32) & Chr(32) & Chr(32) & Chr(32)
  Dim textNumPerSheet As Long
  textNumPerSheet = 1000
  Dim sheetBegin As Long
  sheetBegin = 1
  Dim rowBegin As Long
  rowBegin = 2
  For sheetCurrent = sheetBegin To ActiveWorkbook.Worksheets.Count

    'シートごとの処理
    Dim sheet As Worksheet
    Set sheet = Worksheets(sheetCurrent)

    Dim row As Long
    Dim rowEnd As Long
    rowEnd = sheet.Range("B2").End(xlDown).row
 
    'シートの最初のラベルの定義
    strLabel = strLabel & strIndent & UCase(sheet.Name) & "_START = " & (sheetCurrent - sheetBegin) * textNumPerSheet & "," & Chr(13) & Chr(10)

    'シートの各ラベル
    For row = rowBegin To rowEnd
       If Len(Application.Trim(sheet.Cells(row, 3))) = 0 Then
            Exit For
       End If
       strLabel = strLabel & strIndent & sheet.Cells(row, 2) & " = " & (sheetCurrent - sheetBegin) * textNumPerSheet + (row - rowBegin) & "," & Chr(13) & Chr(10)
    Next row

    'シートの最後のラベルの定義
    strLabel = strLabel & strIndent & UCase(sheet.Name) & "_END = " & (sheetCurrent - sheetBegin) * textNumPerSheet + (row - rowBegin) & "," & Chr(13) & Chr(10)
 
    'シートが変わるので改行
    strLabel = strLabel & Chr(13) & Chr(10)

  Next sheetCurrent

  'ラベル書き込み
  adoStream.WriteText strLabel, 1
  
  'ファイルフッタ書き込み
  adoStream.WriteText strIndent & "NUM", 1
  adoStream.WriteText "}", 1
  adoStream.WriteText "//-----------------------------------------------------------------------------", 1
  adoStream.WriteText "// EOF", 1
  adoStream.WriteText "//-----------------------------------------------------------------------------", 1

  'ファイルセーブ
  adoStream.SaveToFile StrFileName, 2

  'ファイルを閉じる
  adoStream.Close
  Set adoStream = Nothing

  MsgBox "Succeeded in converting text label file."

End Sub

マクロを作ったら実行してAssets/GameData/TextData/TextDataLabel.csが出力されるのを確認します。

テキストデータ管理クラスを作成

固定データ・可変データと同様にテキストデータを管理するクラスを作成します。 Assets/GameData/TextDataにTextDataManager.csを作成します。

using UnityEngine;
using UnityEngine.Assertions;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

public static class TextDataManager
{
    private static TextData textData = null;

    static TextDataManager()
    {
    }

    public static bool Serialize()
    {
        TextAsset serializeFile = Resources.Load("TextData/TextData") as TextAsset;
        using (MemoryStream memoryStream = new MemoryStream(serializeFile.bytes))
        {
            BinaryFormatter binaryFormatter = new BinaryFormatter();
            textData = binaryFormatter.Deserialize(memoryStream) as TextData;
        }

        return true;
    }

    public static string GetText(TEXT_LABEL textLabel)
    {
        Assert.IsTrue(textLabel < TEXT_LABEL.NUM);

        // テキストデータ取得.
        return textData.TextList[(int)textLabel];
    }

}

Assets/GameData/GameDataManager.csを修正します。

    public static void Initialize()
    {
        // 固定データのロード.
        FixedDataManager.Serialize();

        // 可変データの新規作成.
        VariableDataManager.CreateData();

        // ここからを追加.
        // テキストデータのロード.
        TextDataManager.Serialize();
        // ここまでを追加.
    }

適当なところで
TextDataManager.GetText(TEXT_LABEL.SYSTEM_BACK_TO_TITLE);
TextDataManager.GetText(TEXT_LABEL.MONSTER_NAME_0);
等を呼んで文字列を取得できることを確認します。

固定データからテキストデータを参照

固定データのモンスターデータからテキストデータのモンスター名を参照できるようにします。
Assets/Editor/GameData/fixedData.xslxを開いて、Monsterシートに"名前"というカラムを追加しTextDataLabel.csに定義された数値を代入します。

Assets/GameData/FixedData/FixedMonsterData.csを以下のように修正

(略)

    private int _agility = 0;
    public int agilty
    {
        get { return _agility; }
#if UNITY_EDITOR
        set { _agility = value; }
#endif // UNITY_EDITOR
    }

    // ここからを追加.
    private int _name = 0;
    public int name
    {
        get { return _name; }
#if UNITY_EDITOR
        set { _name = value; }
#endif // UNITY_EDITOR
    }
    // ここまでを追加.

    public FixedMonsterData()
    {
    }

    // ここからを追加.
    public string GetName()
    {
        return TextDataManager.GetText((TEXT_LABEL)name);
    }
    // ここまでを追加.

}

Assets/Editor/FixedDataConverter.csに追加されたカラムのコンバート処理を追記

(略)

    private enum MONSTER_COLUMN
    {
        ID,
        COLUMN_B, // 不使用.
        HP,
        MP,
        ATK,
        DEF,
        AGI,
        NAME, // これを追加.
    }

(略)

                        case MONSTER_COLUMN.AGI:
                            {
                                data.agilty = (int)cell.NumericCellValue;
                            }
                            break;
                        // ここからを追加.
                        case MONSTER_COLUMN.NAME:
                            {
                                data.name = (int)cell.NumericCellValue;
                            }
                            break;
                            // ここまでを追加.
                        default:
                            {
                                break;
                            }
                    }
(略)

モンスターデータを再度コンバートして
FixedDataManager.GetMonsterData(int).GetName();
でモンスター名が取得できることを確認します。