【Unity】解析Excel数据,自动创建对应的C#类,创建ScriptableObject的Asset文件并赋值

解析流程:

1. 配置Excel

2. 读取解析Excel

3. 整理解析到的数据

4. 自动创建对应的C#类,继承ScriptableObject,声明变量,保存.cs文件

5. 自动创建ScriptableObject的Asset文件,并赋值,保存Asset文件

6. 在游戏直接使用ScriptableObject类

优点:

1. 每个Excel对应一个类,使用灵活,对Excel限制少

2. 自动创建C#类,不需要对每个Excel手动写代码,Excel修改后重新生成类即可

3. 自动创建ScriptableObject的Asset文件,自动对类字段赋值

4. 数据值直接写到ScriptableObject里,方便查看,可以手动修改调整,不需要每次改动都在Excel里操作

5. 在游戏内直接调用ScriptableObject类,不需要额外操作

具体操作:

1. 配置Excel

2. 读取Excel

#if UNITY_EDITOR

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

//Excel中间数据
public class ExcelMediumData
{
    //Excel名字
    public string excelName;
    //Dictionary<字段名称, 字段类型>,记录类的所有字段及其类型
    public Dictionary<string, string> propertyNameTypeDic;
    //List<一行数据>,List<Dictionary<字段名称, 一行的每个单元格字段值>>
    //记录类的所有字段值,按行记录
    public List<Dictionary<string, string>> allItemValueRowList;
}

public static class ExcelDataReader
{
    //Excel第2行对应字段名称
    const int excelNameRow = 2;
    //Excel第4行对应字段类型
    const int excelTypeRow = 4;
    //Excel第5行及以后对应字段值
    const int excelDataRow = 5;

    //Excel读取路径
    //public static string excelFilePath = Application.dataPath + "/Excel";
    public static string excelFilePath = Application.dataPath.Replace("Assets", "Excel");

    //自动生成C#类文件路径
    static string excelCodePath = Application.dataPath + "/Script/Excel/AutoCreateCSCode";
    //自动生成Asset文件路径
    static string excelAssetPath = "Assets/Resources/ExcelAsset";

    #region --- Read Excel ---

    //创建Excel对应的C#类
    public static void ReadAllExcelToCode()
    {
        //读取所有Excel文件
        //指定目录中与指定的搜索模式和选项匹配的文件的完整名称(包含路径)的数组;如果未找到任何文件,则为空数组。
        string[] excelFileFullPaths = Directory.GetFiles(excelFilePath, "*.xlsx");

        if (excelFileFullPaths == null || excelFileFullPaths.Length == 0)
        {
            Debug.Log("Excel file count == 0");
            return;
        }
        //遍历所有Excel,创建C#类
        for (int i = 0; i < excelFileFullPaths.Length; i++)
        {
            ReadOneExcelToCode(excelFileFullPaths[i]);
        }
    }

    //创建Excel对应的C#类
    public static void ReadOneExcelToCode(string excelFileFullPath)
    {
        //解析Excel获取中间数据
        ExcelMediumData excelMediumData = CreateClassCodeByExcelPath(excelFileFullPath);
        if (excelMediumData != null)
        {
            //根据数据生成C#脚本
            string classCodeStr = ExcelCodeCreater.CreateCodeStrByExcelData(excelMediumData);
            if (!string.IsNullOrEmpty(classCodeStr))
            {
                //写文件,生成CSharp.cs
                if (WriteCodeStrToSave(excelCodePath, excelMediumData.excelName + "ExcelData", classCodeStr))
                {
                    Debug.Log("<color=green>Auto Create Excel Scripts Success : </color>" + excelMediumData.excelName);
                    return;
                }
            }
        }
        //生成失败
        Debug.LogError("Auto Create Excel Scripts Fail : " + (excelMediumData == null ? "" : excelMediumData.excelName));
    }

    #endregion

    #region --- Create Asset ---

    //创建Excel对应的Asset数据文件
    public static void CreateAllExcelAsset()
    {
        //读取所有Excel文件
        //指定目录中与指定的搜索模式和选项匹配的文件的完整名称(包含路径)的数组;如果未找到任何文件,则为空数组。
        string[] excelFileFullPaths = Directory.GetFiles(excelFilePath, "*.xlsx");
        if (excelFileFullPaths == null || excelFileFullPaths.Length == 0)
        {
            Debug.Log("Excel file count == 0");
            return;
        }
        //遍历所有Excel,创建Asset
        for (int i = 0; i < excelFileFullPaths.Length; i++)
        {
            CreateOneExcelAsset(excelFileFullPaths[i]);
        }
    }

    //创建Excel对应的Asset数据文件
    public static void CreateOneExcelAsset(string excelFileFullPath)
    {
        //解析Excel获取中间数据
        ExcelMediumData excelMediumData = CreateClassCodeByExcelPath(excelFileFullPath);
        if (excelMediumData != null)
        {
            ////获取当前程序集
            //Assembly assembly = Assembly.GetExecutingAssembly();
            ////创建类的实例,返回为 object 类型,需要强制类型转换,assembly.CreateInstance("类的完全限定名(即包括命名空间)");
            //object class0bj = assembly.CreateInstance(excelMediumData.excelName + "Assignment",true);

            //必须遍历所有程序集来获得类型。当前在Assembly-CSharp-Editor中,目标类型在Assembly-CSharp中,不同程序将无法获取类型
            Type type = null;
            foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
            {
                //查找目标类型
                Type tempType = asm.GetType(excelMediumData.excelName + "AssetAssignment");
                if (tempType != null)
                {
                    type = tempType;
                    break;
                }
            }
            if (type != null)
            {
                //反射获取方法
                MethodInfo methodInfo = type.GetMethod("CreateAsset");
                if (methodInfo != null)
                {
                    methodInfo.Invoke(null, new object[] { excelMediumData.allItemValueRowList, excelAssetPath });
                    //创建Asset文件成功
                    Debug.Log("<color=green>Auto Create Excel Asset Success : </color>" + excelMediumData.excelName);
                    return;
                }
            }
        }
        //创建Asset文件失败
        Debug.LogError("Auto Create Excel Asset Fail : " + (excelMediumData == null ? "" : excelMediumData.excelName));
    }

    #endregion

    #region --- private ---

    //解析Excel,创建中间数据
    private static ExcelMediumData CreateClassCodeByExcelPath(string excelFileFullPath)
    {
        if (string.IsNullOrEmpty(excelFileFullPath))
            return null;

        excelFileFullPath = excelFileFullPath.Replace("\\", "/");

        FileStream stream = File.Open(excelFileFullPath, FileMode.Open, FileAccess.Read);
        if (stream == null)
            return null;
        //解析Excel
        IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
        //无效Excel
        if (excelReader == null || !excelReader.IsValid)
        {
            Debug.Log("Invalid excel : " + excelFileFullPath);
            return null;
        }

        //<数据名称,数据类型>
        KeyValuePair<string, string>[] propertyNameTypes = null;
        //List<KeyValuePair<数据名称, 单元格数据值>[]>,所有数据值,按行记录
        List<Dictionary<string, string>> allItemValueRowList = new List<Dictionary<string, string>>();

        //每行数据数量
        int propertyCount = 0;
        //当前遍历行,从1开始
        int curRowIndex = 1;
        //开始读取,按行遍历
        while (excelReader.Read())
        {
            if (excelReader.FieldCount == 0)
                continue;
            //读取一行的数据
            string[] datas = new string[excelReader.FieldCount];
            for (int j = 0; j < excelReader.FieldCount; ++j)
            {
                //赋值一行的每一个单元格数据
                datas[j] = excelReader.GetString(j);
            }
            //空行/行第一个单元格为空,视为无效数据
            if (datas.Length == 0 || string.IsNullOrEmpty(datas[0]))
            {
                curRowIndex++;
                continue;
            }
            //数据行
            if (curRowIndex >= excelDataRow)
            {
                //数据无效
                if (propertyCount <= 0)
                    return null;

                Dictionary<string, string> itemDic = new Dictionary<string, string>(propertyCount);
                //遍历一行里的每个单元格数据
                for (int j = 0; j < propertyCount; j++)
                {
                    //判断长度
                    if (j < datas.Length)
                        itemDic[propertyNameTypes[j].Key] = datas[j];
                    else
                        itemDic[propertyNameTypes[j].Key] = null;
                }
                allItemValueRowList.Add(itemDic);
            }
            //数据名称行
            else if (curRowIndex == excelNameRow)
            {
                //以数据名称确定每行的数据数量
                propertyCount = datas.Length;
                if (propertyCount <= 0)
                    return null;
                //记录数据名称
                propertyNameTypes = new KeyValuePair<string, string>[propertyCount];
                for (int i = 0; i < propertyCount; i++)
                {
                    propertyNameTypes[i] = new KeyValuePair<string, string>(datas[i], null);
                }
            }
            //数据类型行
            else if (curRowIndex == excelTypeRow)
            {
                //数据类型数量少于指定数量,数据无效
                if (propertyCount <= 0 || datas.Length < propertyCount)
                    return null;
                //记录数据名称及类型
                for (int i = 0; i < propertyCount; i++)
                {
                    propertyNameTypes[i] = new KeyValuePair<string, string>(propertyNameTypes[i].Key, datas[i]);
                }
            }
            curRowIndex++;
        }

        if (propertyNameTypes.Length == 0 || allItemValueRowList.Count == 0)
            return null;

        ExcelMediumData excelMediumData = new ExcelMediumData();
        //类名
        excelMediumData.excelName = excelReader.Name;
        //Dictionary<数据名称,数据类型>
        excelMediumData.propertyNameTypeDic = new Dictionary<string, string>();
        //转换存储格式
        for (int i = 0; i < propertyCount; i++)
        {
            //数据名重复,数据无效
            if (excelMediumData.propertyNameTypeDic.ContainsKey(propertyNameTypes[i].Key))
                return null;
            excelMediumData.propertyNameTypeDic.Add(propertyNameTypes[i].Key, propertyNameTypes[i].Value);
        }
        excelMediumData.allItemValueRowList = allItemValueRowList;
        return excelMediumData;
    }

    //写文件
    private static bool WriteCodeStrToSave(string writeFilePath, string codeFileName, string classCodeStr)
    {
        if (string.IsNullOrEmpty(codeFileName) || string.IsNullOrEmpty(classCodeStr))
            return false;
        //检查导出路径
        if (!Directory.Exists(writeFilePath))
            Directory.CreateDirectory(writeFilePath);
        //写文件,生成CS类文件
        StreamWriter sw = new StreamWriter(writeFilePath + "/" + codeFileName + ".cs");
        sw.WriteLine(classCodeStr);
        sw.Close();
        //
        UnityEditor.AssetDatabase.Refresh();
        return true;
    }

    #endregion

}
#endif

3.  自动生成C#类和Asset文件

#if UNITY_EDITOR

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Text;

public class ExcelCodeCreater
{

    #region --- Create Code ---

    //创建代码,生成数据C#类
    public static string CreateCodeStrByExcelData(ExcelMediumData excelMediumData)
    {
        if (excelMediumData == null)
            return null;
        //Excel名字
        string excelName = excelMediumData.excelName;
        if (string.IsNullOrEmpty(excelName))
            return null;
        //Dictionary<字段名称, 字段类型>
        Dictionary<string, string> propertyNameTypeDic = excelMediumData.propertyNameTypeDic;
        if (propertyNameTypeDic == null || propertyNameTypeDic.Count == 0)
            return null;
        //List<一行数据>,List<Dictionary<字段名称, 一行的每个单元格字段值>>
        List<Dictionary<string, string>> allItemValueRowList = excelMediumData.allItemValueRowList;
        if (allItemValueRowList == null || allItemValueRowList.Count == 0)
            return null;
        //行数据类名
        string itemClassName = excelName + "ExcelItem";
        //整体数据类名
        string dataClassName = excelName + "ExcelData";

        //生成类
        StringBuilder classSource = new StringBuilder();
        classSource.Append("/*Auto Create, Don't Edit !!!*/\n");
        classSource.Append("\n");
        //添加引用
        classSource.Append("using UnityEngine;\n");
        classSource.Append("using System.Collections.Generic;\n");
        classSource.Append("using System;\n");
        classSource.Append("using System.IO;\n");
        classSource.Append("\n");
        //生成行数据类,记录每行数据
        classSource.Append(CreateExcelRowItemClass(itemClassName, propertyNameTypeDic));
        classSource.Append("\n");
        //生成整体数据类,记录整个Excel的所有行数据
        classSource.Append(CreateExcelDataClass(dataClassName, itemClassName));
        classSource.Append("\n");
        //生成Asset操作类,用于自动创建Excel对应的Asset文件并赋值
        classSource.Append(CreateExcelAssetClass(excelMediumData));
        classSource.Append("\n");
        return classSource.ToString();
    }

    //----------

    //生成行数据类
    private static StringBuilder CreateExcelRowItemClass(string itemClassName, Dictionary<string, string> propertyNameTypeDic)
    {
        //生成Excel行数据类
        StringBuilder classSource = new StringBuilder();
        classSource.Append("[Serializable]\n");
        classSource.Append("public class " + itemClassName + " : ExcelItemBase\n");
        classSource.Append("{\n");
        //声明所有字段
        foreach (var item in propertyNameTypeDic)
        {
            classSource.Append(CreateCodeProperty(item.Key, item.Value));
        }
        classSource.Append("}\n");
        return classSource;
    }

    //声明行数据类字段
    private static string CreateCodeProperty(string name, string type)
    {
        if (string.IsNullOrEmpty(name))
            return null;
        if (name == "id")
            return null;

        //判断字段类型
        if (type == "int" || type == "Int" || type == "INT")
            type = "int";
        else if (type == "float" || type == "Float" || type == "FLOAT")
            type = "float";
        else if (type == "bool" || type == "Bool" || type == "BOOL")
            type = "bool";
        else
            type = "string";
        //声明
        string propertyStr = "\tpublic " + type + " " + name + ";\n";
        return propertyStr;
    }

    //----------

    //生成数据类
    private static StringBuilder CreateExcelDataClass(string dataClassName, string itemClassName)
    {
        StringBuilder classSource = new StringBuilder();
        classSource.Append("[CreateAssetMenu(fileName = \"" + dataClassName + "\", menuName = \"Excel To ScriptableObject/Create " + dataClassName + "\", order = 1)]\n");
        classSource.Append("public class " + dataClassName + " : ExcelDataBase<" + itemClassName + ">\n");
        classSource.Append("{\n");
        //声明字段,行数据类数组
        //classSource.Append("\tpublic " + itemClassName + "[] items;\n");
        classSource.Append("}\n");
        return classSource;
    }

    //----------

    //生成Asset操作类
    private static StringBuilder CreateExcelAssetClass(ExcelMediumData excelMediumData)
    {
        if (excelMediumData == null)
            return null;

        string excelName = excelMediumData.excelName;
        if (string.IsNullOrEmpty(excelName))
            return null;

        Dictionary<string, string> propertyNameTypeDic = excelMediumData.propertyNameTypeDic;
        if (propertyNameTypeDic == null || propertyNameTypeDic.Count == 0)
            return null;

        List<Dictionary<string, string>> allItemValueRowList = excelMediumData.allItemValueRowList;
        if (allItemValueRowList == null || allItemValueRowList.Count == 0)
            return null;

        string itemClassName = excelName + "ExcelItem";
        string dataClassName = excelName + "ExcelData";

        StringBuilder classSource = new StringBuilder();
        classSource.Append("#if UNITY_EDITOR\n");
        //类名
        classSource.Append("public class " + excelName + "AssetAssignment\n");
        classSource.Append("{\n");
        //方法名
        classSource.Append("\tpublic static bool CreateAsset(List<Dictionary<string, string>> allItemValueRowList, string excelAssetPath)\n");
        //方法体,若有需要可加入try/catch
        classSource.Append("\t{\n");
        classSource.Append("\t\tif (allItemValueRowList == null || allItemValueRowList.Count == 0)\n");
        classSource.Append("\t\t\treturn false;\n");
        classSource.Append("\t\tint rowCount = allItemValueRowList.Count;\n");
        classSource.Append("\t\t" + itemClassName + "[] items = new " + itemClassName + "[rowCount];\n");
        classSource.Append("\t\tfor (int i = 0; i < items.Length; i++)\n");
        classSource.Append("\t\t{\n");
        classSource.Append("\t\t\titems[i] = new " + itemClassName + "();\n");
        foreach (var item in propertyNameTypeDic)
        {
            classSource.Append("\t\t\titems[i]." + item.Key + " = ");

            classSource.Append(AssignmentCodeProperty("allItemValueRowList[i][\"" + item.Key + "\"]", propertyNameTypeDic[item.Key]));
            classSource.Append(";\n");
        }
        classSource.Append("\t\t}\n");
        classSource.Append("\t\t" + dataClassName + " excelDataAsset = ScriptableObject.CreateInstance<" + dataClassName + ">();\n");
        classSource.Append("\t\texcelDataAsset.items = items;\n");
        classSource.Append("\t\tif (!Directory.Exists(excelAssetPath))\n");
        classSource.Append("\t\t\tDirectory.CreateDirectory(excelAssetPath);\n");
        classSource.Append("\t\tstring pullPath = excelAssetPath + \"/\" + typeof(" + dataClassName + ").Name + \".asset\";\n");
        classSource.Append("\t\tUnityEditor.AssetDatabase.DeleteAsset(pullPath);\n");
        classSource.Append("\t\tUnityEditor.AssetDatabase.CreateAsset(excelDataAsset, pullPath);\n");
        classSource.Append("\t\tUnityEditor.AssetDatabase.Refresh();\n");
        classSource.Append("\t\treturn true;\n");
        classSource.Append("\t}\n");
        //
        classSource.Append("}\n");
        classSource.Append("#endif\n");
        return classSource;
    }

    //声明Asset操作类字段
    private static string AssignmentCodeProperty(string stringValue, string type)
    {
        //判断类型
        if (type == "int" || type == "Int" || type == "INT")
        {
            return "Convert.ToInt32(" + stringValue + ")";
        }
        else if (type == "float" || type == "Float" || type == "FLOAT")
        {
            return "Convert.ToSingle(" + stringValue + ")";
        }
        else if (type == "bool" || type == "Bool" || type == "BOOL")
        {
            return "Convert.ToBoolean(" + stringValue + ")";
        }
        else
            return stringValue;
    }

    #endregion

}
#endif

4.  编写操作面板窗口

#if UNITY_EDITOR

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

public class BuildExcelEditor : Editor
{

}

public class BuildExcelWindow : EditorWindow
{
    //[MenuItem("MyTools/Excel/Build Script")]
    //public static void CreateExcelCode()
    //{
    //    ExcelDataReader.ReadAllExcelToCode();
    //}

    //[MenuItem("MyTools/Excel/Build Asset")]
    //public static void CreateExcelAssset()
    //{
    //    ExcelDataReader.CreateAllExcelAsset();
    //}

    [MenuItem("MyTools/Excel/Build Window")]
    public static void ShowExcelWindow()
    {
        //显示操作窗口方式一
        //BuildExcelWindow buildExcelWindow = GetWindow<BuildExcelWindow>();
        //buildExcelWindow.Show();
        //显示操作窗口方式二
        EditorWindow.GetWindow(typeof(BuildExcelWindow));
    }

    private string showNotify;
    private Vector2 scrollPosition = Vector2.zero;

    private List<string> fileNameList = new List<string>();
    private List<string> filePathList = new List<string>();

    private void Awake()
    {
        titleContent.text = "Excel数据读取";
    }

    private void OnEnable()
    {
        showNotify = "";
        GetExcelFile();
    }

    private void OnDisable()
    {
        showNotify = "";

        fileNameList.Clear();
        filePathList.Clear();
    }

    private void OnGUI()
    {
        scrollPosition = GUILayout.BeginScrollView(scrollPosition,
            GUILayout.Width(position.width), GUILayout.Height(position.height));
        //自动创建C#脚本
        GUILayout.Space(10);
        GUILayout.Label("Excel To Script");
        for (int i = 0; i < fileNameList.Count; i++)
        {
            if (GUILayout.Button(fileNameList[i], GUILayout.Width(200), GUILayout.Height(30)))
            {
                SelectExcelToCodeByIndex(i);
            }
        }
        if (GUILayout.Button("All Excel", GUILayout.Width(200), GUILayout.Height(30)))
        {
            SelectExcelToCodeByIndex(-1);
        }
        //自动创建Asset文件
        GUILayout.Space(20);
        GUILayout.Label("Script To Asset");
        for (int i = 0; i < fileNameList.Count; i++)
        {
            if (GUILayout.Button(fileNameList[i], GUILayout.Width(200), GUILayout.Height(30)))
            {
                SelectCodeToAssetByIndex(i);
            }
        }
        if (GUILayout.Button("All Excel", GUILayout.Width(200), GUILayout.Height(30)))
        {
            SelectCodeToAssetByIndex(-1);
        }
        //
        GUILayout.Space(20);
        GUILayout.Label(showNotify);
        //
        GUILayout.EndScrollView();
        //this.Repaint();
    }

    //读取指定路径下的Excel文件名
    private void GetExcelFile()
    {
        fileNameList.Clear();
        filePathList.Clear();

        if (!Directory.Exists(ExcelDataReader.excelFilePath))
        {
            showNotify = "无效路径:" + ExcelDataReader.excelFilePath;
            return;
        }
        string[] excelFileFullPaths = Directory.GetFiles(ExcelDataReader.excelFilePath, "*.xlsx");

        if (excelFileFullPaths == null || excelFileFullPaths.Length == 0)
        {
            showNotify = ExcelDataReader.excelFilePath + "路径下没有找到Excel文件";
            return;
        }

        filePathList.AddRange(excelFileFullPaths);
        for (int i = 0; i < filePathList.Count; i++)
        {
            string fileName = filePathList[i].Split('/').LastOrDefault();
            fileName = filePathList[i].Split('\\').LastOrDefault();
            fileNameList.Add(fileName);
        }
        showNotify = "找到Excel文件:" + fileNameList.Count + "个";
    }

    //自动创建C#脚本
    private void SelectExcelToCodeByIndex(int index)
    {
        if (index >= 0 && index < filePathList.Count)
        {
            string fullPath = filePathList[index];
            ExcelDataReader.ReadOneExcelToCode(fullPath);
        }
        else
        {
            ExcelDataReader.ReadAllExcelToCode();
        }
    }

    //自动创建Asset文件
    private void SelectCodeToAssetByIndex(int index)
    {
        if (index >= 0 && index < filePathList.Count)
        {
            string fullPath = filePathList[index];
            ExcelDataReader.CreateOneExcelAsset(fullPath);
        }
        else
        {
            ExcelDataReader.CreateAllExcelAsset();
        }
    }
}

#endif

5.  操作成功,游戏内使用数据

表格数据类基类

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

public class ExcelDataBase<T> : ScriptableObject where T : ExcelItemBase
{
    public T[] items;

    public T GetExcelItem(string targetId)
    {
        if(items != null && items.Length > 0)
        {
            return items.FirstOrDefault(item => item.id == targetId);
        }
        return null;
    }
}

public class ExcelItemBase
{
    public string id;
}

自动创建的C#类:

/*Auto Create, Don't Edit !!!*/

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

[Serializable]
public class RoleParameExcelItem : ExcelItemBase
{
	public int attack;
	public int maxHealth;
	public int energySpeed;
	public int maxEnergy;
	public float mass;
	public int maxSpeed;
	public int acceleration;
	public float critProbability;
	public float critValue;
	public float angryTime;
	public float angrySpeed;
	public float bounceTime;
	public float resist;
	public int skillLevel;
}

[CreateAssetMenu(fileName = "RoleParameExcelData", menuName = "Excel To ScriptableObject/Create RoleParameExcelData", order = 1)]
public class RoleParameExcelData : ExcelDataBase<RoleParameExcelItem>
{
}

#if UNITY_EDITOR
public class RoleParameAssetAssignment
{
	public static bool CreateAsset(List<Dictionary<string, string>> allItemValueRowList, string excelAssetPath)
	{
		if (allItemValueRowList == null || allItemValueRowList.Count == 0)
			return false;
		int rowCount = allItemValueRowList.Count;
		RoleParameExcelItem[] items = new RoleParameExcelItem[rowCount];
		for (int i = 0; i < items.Length; i++)
		{
			items[i] = new RoleParameExcelItem();
			items[i].id = allItemValueRowList[i]["id"];
			items[i].attack = Convert.ToInt32(allItemValueRowList[i]["attack"]);
			items[i].maxHealth = Convert.ToInt32(allItemValueRowList[i]["maxHealth"]);
			items[i].energySpeed = Convert.ToInt32(allItemValueRowList[i]["energySpeed"]);
			items[i].maxEnergy = Convert.ToInt32(allItemValueRowList[i]["maxEnergy"]);
			items[i].mass = Convert.ToSingle(allItemValueRowList[i]["mass"]);
			items[i].maxSpeed = Convert.ToInt32(allItemValueRowList[i]["maxSpeed"]);
			items[i].acceleration = Convert.ToInt32(allItemValueRowList[i]["acceleration"]);
			items[i].critProbability = Convert.ToSingle(allItemValueRowList[i]["critProbability"]);
			items[i].critValue = Convert.ToSingle(allItemValueRowList[i]["critValue"]);
			items[i].angryTime = Convert.ToSingle(allItemValueRowList[i]["angryTime"]);
			items[i].angrySpeed = Convert.ToSingle(allItemValueRowList[i]["angrySpeed"]);
			items[i].bounceTime = Convert.ToSingle(allItemValueRowList[i]["bounceTime"]);
			items[i].resist = Convert.ToSingle(allItemValueRowList[i]["resist"]);
			items[i].skillLevel = Convert.ToInt32(allItemValueRowList[i]["skillLevel"]);
		}
		RoleParameExcelData excelDataAsset = ScriptableObject.CreateInstance<RoleParameExcelData>();
		excelDataAsset.items = items;
		if (!Directory.Exists(excelAssetPath))
			Directory.CreateDirectory(excelAssetPath);
		string pullPath = excelAssetPath + "/" + typeof(RoleParameExcelData).Name + ".asset";
		UnityEditor.AssetDatabase.DeleteAsset(pullPath);
		UnityEditor.AssetDatabase.CreateAsset(excelDataAsset, pullPath);
		UnityEditor.AssetDatabase.Refresh();
		return true;
	}
}
#endif

自动创建的ScriptableObject对应Asset文件 

测试用管理类

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

public class ExcelManager : CSSingleton<ExcelManager>
{
    Dictionary<Type, ExcelDataBase<ExcelItemBase>> excelDataDic = new Dictionary<Type, ExcelDataBase<ExcelItemBase>>();

    public void Init()
    {

    }

    public T GetExcelData<T, V>() where T : ExcelDataBase<V> where V : ExcelItemBase
    {
        Type type = typeof(T);
        if (excelDataDic.ContainsKey(type))
            return excelDataDic[type] as T;

        T excelData = LoadManager.ResourcesLoad<T>(ConstConfig.excelAssetResourcesPath, type.Name);
        if (excelData != null)
            excelDataDic.Add(type, excelData as ExcelDataBase<ExcelItemBase>);
        return excelData;
    }

    public V GetExcelItem<T, V>(string targetId) where T : ExcelDataBase<V> where V : ExcelItemBase
    {
        Type type = typeof(T);
        T excelData = GetExcelData<T, V>();
        if (excelData != null)
            return excelData.GetExcelItem(targetId);
        return null;
    }

}

测试游戏内使用

public class ExcelTest : MonoBehaviour
{
    void Start()
    {
        RoleParameExcelData roleParameExcelData = Resources.Load<RoleParameExcelData>("ExcelAsset/RoleParameExcelData");
        if(roleParameExcelData != null)
        {
            for (int i = 0; i < roleParameExcelData.items.Length; i++)
            {
                Debug.Log(roleParameExcelData.items[i].id);
            }
        }
    }
}

 

发布了104 篇原创文章 · 获赞 73 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_39108767/article/details/105607347
今日推荐