Ananke Csv Master 4.Generating ScriptableObjects

Back to Table of Contents

Creating ScriptableObjects

After configuring your DataSet, click the “Create ScriptableObject and Importer” button in the Actions area.

Note: Since files are generated per Group, you can configure all DataSets within a group before generating.
For example, we can set up the ExpTable DataSet and generate everything at once.

Our ExpTable settings are as follows:

The generated source code files will be output to the locations specified in your initial Settings:

ScriptableObject Class Path: Output location for ScriptableObject classes
Importer Path: Location for importer files

Example ScriptableObject Class Output

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; }
    }

}

Note: While the code shows Int32, this is internally identical to int. You can use int in your code without any casting.

The importer code, though lengthy, handles type conversion and stores values in the ScriptableObject instance.

Example Importer Output

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}");
                }
            }
        }

    }
}

Now that we can load data, let’s create actual data and try importing it.

Next

コメント

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