パープルハット

※当サイトではGoogleアドセンス広告を利用しています

Unity エディタ拡張 CSVファイルからScriptableObjectの作成




概要

CSVファイルからScriptableObjectを作成する方法をまとめてみました。
今回は「EditorWindow」を使う方法をとっています。
CSVファイルの読み込みについては下の記事を参考にしてください。




スクリプト

CSVファイルを読み込むクラス

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

public static class FileReader
{
    //CSVファイルを読み取る
    public static List<string[]> ReadCSVFile(TextAsset csvFile)
    {
        //1行ごとに配列としてCSV読み取り、それをリストに変換する
        List<string> list = File.ReadAllLines(AssetDatabase.GetAssetPath(csvFile)).ToList();

        //1行ごとの文字列を更に、カンマで区切る
        List<string[]> lists = new List<string[]>();
        for (int i = 0; i < list.Count; i++)
        {
            lists.Add(list[i].Split(','));
        }

        return lists;
    }

    //テキストファイルを読み取る
    public static List<string> ReadTextFile(TextAsset textAsset)
    {
        return File.ReadAllLines(AssetDatabase.GetAssetPath(textAsset)).ToList();
    }
}



EditorWindowでCSVファイルを読み込み、ScriptableObjectを作成するクラス(継承して使用)

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

public abstract class ScriptableObjectCreater<T> : EditorWindow where T : ScriptableObject
{
    [SerializeField] TextAsset csvFile;// CSVファイル
    [SerializeField] string exportFolder;//出力先フォルダ
    [SerializeField] byte startLine = 1;//何行目から読み込むか
    [SerializeField] byte nameLine = 0;//何列目の文字列をScriptableObjectのファイル名にするか

    public void Create()//データの作成
    {
        //CSVファイルを読み込む
        List<string[]> csvLines = FileReader.ReadCSVFile(csvFile);

        //読み取った値からScriptableObjectの作成
        for (int i = startLine; i < csvLines.Count; i++)
        {
            //出力パスを決定
            string fileName = $"{csvLines[i][nameLine]}.asset";
            string exportPath = $"{exportFolder}/{fileName}";

            /*既にデータが存在している場合は上書き、
              そうでない場合は新規にScriptableObjectを生成*/
            T obj;
            if (File.Exists(exportPath))
            {
                obj = AssetDatabase.LoadAssetAtPath(exportPath, typeof(T)) as T;
            }
            else
            {
                //新規作成
                obj = CreateInstance<T>();
                AssetDatabase.CreateAsset(obj, exportPath);
            }

            //キューにデータを保存
            Queue<string> data = new Queue<string>();
            foreach (var csvLine in csvLines[i])
                data.Enqueue(csvLine);

            //データの設定
            SetEachData(obj, data);

            //変更済みのデータであると印をつける
            EditorUtility.SetDirty(obj);
        }
        //保存
        AssetDatabase.SaveAssets();
    }


    //各データを作成する(継承して使用)
    protected abstract void SetEachData(T t, Queue<string> data);

    //エディタウィンドウ上での挙動
    protected void OnGUI()
    {
        csvFile = (TextAsset)EditorGUILayout.ObjectField("CSVファイル", csvFile, typeof(TextAsset), false);
        exportFolder = EditorGUILayout.TextField("出力先フォルダ", exportFolder);
        startLine = (byte)EditorGUILayout.IntField("読み取り開始行番号", startLine);
        nameLine = (byte)EditorGUILayout.IntField("ファイル名とする列番号", nameLine);

        //元のInspector部分の下にボタンを表示
        if (GUILayout.Button("データの設定"))
            Create();
    }
}





使用例

次のCSVファイルから次のScriptableObjectのItemDataを作成する。
CSVファイルはExcelから作成した。

CSVファイル Item.csv

A B C
1 名前 買値 売値
2 木の棒 5 1
3 鍋蓋 10 2
4 甲冑 1000 500


このCSVファイルをメモ帳などで開くと次のようになっています。

名前,買値,売値
木の棒,5,1
鍋蓋,10,2
甲冑,1000,500



注)

  • A列目(名前の列)が作成するScriptableObjectのファイル名になる
  • csvの形式はCSV UTF-8(コンマ区切り)




ItemDataクラス

using UnityEngine;

public class ItemData : ScriptableObject
{
    public string _name;
    public int bidPrice;//買値
    public int sellPrice;//売値
}




CSVファイルを読み込み、Itemを作成するクラス(ScriptableObjectCreaterを継承)

using UnityEditor;
using System.Collections.Generic;

public class ItemDataCreateWindow : ScriptableObjectCreater<ItemData>
{
    [MenuItem("Window/Create/Item")]
    protected static void Init()
    {
        ItemDataCreateWindow window = (ItemDataCreateWindow)GetWindow(typeof(ItemDataCreateWindow));
        window.Show();
    }

    protected override void SetEachData(ItemData item, Queue<string> dataQueue)
    {
        item._name = dataQueue.Dequeue();
        item.bidPrice = int.Parse(dataQueue.Dequeue());
        item.sellPrice = int.Parse(dataQueue.Dequeue());
    }
}




使用方法

1. エディタで「Window」⇒「Create」⇒「Item」の順にクリックし、「ItemDataCreateWindow」を作成する。


2. 作成したウィンドウに対して変数の設定を行う(今回は「Assets」フォルダ直下に作成した「ItemData」に保存する)。


3. 「データの設定」ボタンを押すと以下のようにファイルが生成される。