Ananke Csv Master 4.ScriptableObjectを生成する

もくじへ

ScriptableObjectを生成する

DataSetの設定が終わったら、Actions領域の「Create ScriptableObject and Importer」ボタンをクリックします。

これはGroup単位で1つのファイルとなっているので、Group配下に複数のデータセットがある場合には、全てのDataSetを作成し終わってからでも問題ありません。

というわけで、続けてExpTableのDataSetの設定を行い、再度出力してみます。

ExpTableの設定は以下としました。

このとき出力されるソースコードの場所は最初にSettingで指定した場所になります。

ScriptableObject Class Path:ScriptableObjectクラスの出力先
Importer Path : インポーターのパス

ScriptableObjectクラス 出力例

using System;
using UnityEngine;
using CatHut;

[CreateAssetMenu(fileName = "Player", menuName = "CatHut/ScriptableObjects/Player")]
public class Player : ScriptableObject
{
    public enum JOB
    {
        NONE = 0,
        HERO,
        KNIGHT,
        HEALER,
        FIGHTER
    }

    [SerializeField] private SerializableDictionary<string, Character> _CharacterData;
    public SerializableDictionary<string, Character> CharacterData { get => _CharacterData; set => _CharacterData = value; }
    [SerializeField] private SerializableDictionary<string, ExpTable> _ExpTableData;
    public SerializableDictionary<string, ExpTable> ExpTableData { get => _ExpTableData; set => _ExpTableData = value; }

    [Serializable]
    public class Character : MasterDataBase
    {
        [SerializeField] private string _id;
        public string id { get => _id; set => _id = value; }

        [SerializeField] private String _Name;
        [SerializeField] private JOB _Job;
        [SerializeField] private Int32 _Hp;
        [SerializeField] private Int32 _Mp;
        [SerializeField] private Int32 _Atk;
        [SerializeField] private Int32 _Def;

        public String Name { get => _Name; set => _Name = value; }
        public JOB Job { get => _Job; set => _Job = value; }
        public Int32 Hp { get => _Hp; set => _Hp = value; }
        public Int32 Mp { get => _Mp; set => _Mp = value; }
        public Int32 Atk { get => _Atk; set => _Atk = value; }
        public Int32 Def { get => _Def; set => _Def = value; }
    }

    [Serializable]
    public class ExpTable : MasterDataBase
    {
        [SerializeField] private string _id;
        public string id { get => _id; set => _id = value; }

        [SerializeField] private Int32 _Lv;
        [SerializeField] private Int32 _Exp;

        public Int32 Lv { get => _Lv; set => _Lv = value; }
        public Int32 Exp { get => _Exp; set => _Exp = value; }
    }

}

intがInt32となっていますが、これは内部的には同じものなのでコードで使うときにもintとして使用可能なもので、キャストも不要です。

また、少し長いですが、Importerは下記のようなものが出力されます。
それぞれの型をConvertしながらScriptableObjectのインスタンスに値を格納します。
Importer 出力例

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

namespace CatHut
{
    public class PlayerImporter : IDataImporter
    {
        private readonly RawDataGroup _group;
        private readonly Player _instance;

        public PlayerImporter(RawDataGroup group)
        {
            if (group == null)
                throw new ArgumentNullException(nameof(group));

            _group = group;
            _instance = ScriptableObject.CreateInstance<Player>();
            _instance.CharacterData = new SerializableDictionary<string, Player.Character>();
            _instance.ExpTableData = new SerializableDictionary<string, Player.ExpTable>();
        }

        public ScriptableObject Import()
        {
            var CharacterDataSet = _group.GetDataSet("Character");
            if (CharacterDataSet == null)
                throw new InvalidOperationException("Required dataset 'Character' not found");

            if (CharacterDataSet.Header == null)
                throw new InvalidOperationException("Header information is missing for dataset 'Character'");

            ImportCharacterData(CharacterDataSet);

            var ExpTableDataSet = _group.GetDataSet("ExpTable");
            if (ExpTableDataSet == null)
                throw new InvalidOperationException("Required dataset 'ExpTable' not found");

            if (ExpTableDataSet.Header == null)
                throw new InvalidOperationException("Header information is missing for dataset 'ExpTable'");

            ImportExpTableData(ExpTableDataSet);

            return _instance;
        }

        private void ImportCharacterData(RawDataSet dataSet)
        {
            var header = dataSet.Header;

            foreach (var path in dataSet.DataVersions.GetRegisteredPaths())
            {
                var csvData = dataSet.DataVersions.GetVersion(path);
                if (csvData == null)
                    throw new InvalidOperationException($"Failed to get CSV data for path: {path}");

                dataSet.SetColumnIndex(csvData);

                int errorCount = 0;

                for (int rowIndex = 1; rowIndex < csvData.RowCount; rowIndex++)
                {
                    var entry = new Player.Character();
                    bool hasRowError = false;

                    foreach (var variable in header.VariableDic)
                    {
                        if (variable.Value.ColumnIndex >= csvData.ColumnCount)
                        {
                            throw new InvalidOperationException(
                            $"Column index out of range. Variable: {variable.Key}, " +
                            $"Index: {variable.Value.ColumnIndex}, " +
                            $"Available columns: {csvData.ColumnCount}");
                        }

                        var value = csvData.GetValue(rowIndex, variable.Value.ColumnIndex);

                        switch (variable.Key)
                        {
                            case "id":
                                if (!MasterDataEditorCommon.TryConvert<string>(value, out var convertedid))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to string for column 'id' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.id = convertedid;
                                }
                                break;
                            case "Name":
                                if (!MasterDataEditorCommon.TryConvert<string>(value, out var convertedName))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to string for column 'Name' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.Name = convertedName;
                                }
                                break;
                            case "Job":
                                if (!MasterDataEditorCommon.TryConvert<Player.JOB>(value, out var convertedJob))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to Tables[JOB] for column 'Job' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.Job = convertedJob;
                                }
                                break;
                            case "Hp":
                                if (!MasterDataEditorCommon.TryConvert<int>(value, out var convertedHp))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to int for column 'Hp' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.Hp = convertedHp;
                                }
                                break;
                            case "Mp":
                                if (!MasterDataEditorCommon.TryConvert<int>(value, out var convertedMp))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to int for column 'Mp' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.Mp = convertedMp;
                                }
                                break;
                            case "Atk":
                                if (!MasterDataEditorCommon.TryConvert<int>(value, out var convertedAtk))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to int for column 'Atk' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.Atk = convertedAtk;
                                }
                                break;
                            case "Def":
                                if (!MasterDataEditorCommon.TryConvert<int>(value, out var convertedDef))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to int for column 'Def' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.Def = convertedDef;
                                }
                                break;
                        }
                    }

                    if (!hasRowError)
                    {
                        if (_instance.CharacterData.ContainsKey(entry.id))
                        {
                            Debug.LogError($"[{csvData.FilePath}] Duplicate key found. Value: {entry.id}, Row: {rowIndex}");
                            hasRowError = true;
                            errorCount++;
                        }
                        else
                        {
                            _instance.CharacterData[entry.id] = entry;
                        }
                    }
                }

                if (errorCount > 0)
                {
                    Debug.LogError($"Found {errorCount} errors in file: {csvData.FilePath}");
                }
            }
        }

        private void ImportExpTableData(RawDataSet dataSet)
        {
            var header = dataSet.Header;

            foreach (var path in dataSet.DataVersions.GetRegisteredPaths())
            {
                var csvData = dataSet.DataVersions.GetVersion(path);
                if (csvData == null)
                    throw new InvalidOperationException($"Failed to get CSV data for path: {path}");

                dataSet.SetColumnIndex(csvData);

                int errorCount = 0;

                for (int rowIndex = 1; rowIndex < csvData.RowCount; rowIndex++)
                {
                    var entry = new Player.ExpTable();
                    bool hasRowError = false;

                    foreach (var variable in header.VariableDic)
                    {
                        if (variable.Value.ColumnIndex >= csvData.ColumnCount)
                        {
                            throw new InvalidOperationException(
                            $"Column index out of range. Variable: {variable.Key}, " +
                            $"Index: {variable.Value.ColumnIndex}, " +
                            $"Available columns: {csvData.ColumnCount}");
                        }

                        var value = csvData.GetValue(rowIndex, variable.Value.ColumnIndex);

                        switch (variable.Key)
                        {
                            case "id":
                                if (!MasterDataEditorCommon.TryConvert<string>(value, out var convertedid))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to string for column 'id' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.id = convertedid;
                                }
                                break;
                            case "Lv":
                                if (!MasterDataEditorCommon.TryConvert<int>(value, out var convertedLv))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to int for column 'Lv' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.Lv = convertedLv;
                                }
                                break;
                            case "Exp":
                                if (!MasterDataEditorCommon.TryConvert<int>(value, out var convertedExp))
                                {
                                    Debug.LogError($"[{csvData.FilePath}] Failed to convert value '{value}' to int for column 'Exp' at row {rowIndex}");
                                    hasRowError = true;
                                }
                                else
                                {
                                    entry.Exp = convertedExp;
                                }
                                break;
                        }
                    }

                    if (!hasRowError)
                    {
                        if (_instance.ExpTableData.ContainsKey(entry.id))
                        {
                            Debug.LogError($"[{csvData.FilePath}] Duplicate key found. Value: {entry.id}, Row: {rowIndex}");
                            hasRowError = true;
                            errorCount++;
                        }
                        else
                        {
                            _instance.ExpTableData[entry.id] = entry;
                        }
                    }
                }

                if (errorCount > 0)
                {
                    Debug.LogError($"Found {errorCount} errors in file: {csvData.FilePath}");
                }
            }
        }

    }
}

ここまででデータの読み込みが可能になるので、次は実際にデータを作成し、読み込みを行ってみます。

次へ

コメント

タイトルとURLをコピーしました