Unity ScriptableObject 自动导出 .csv文件

发表于2018-03-06
评论0 6.2k浏览
ScriptableObject给客户端用是很好用的,但是,如果给服务器端用,却很麻烦,所以我写了一个自动导出工具,可以以很小的代价,将ScriptableObject的部分字段自动导出到csv文件中,供服务器使用,这样也避免了数据冗余,同时避免策划在填写重复数据的时候出错。

使用ScriptableObject自动导出 .csv文件的思路如下:
1、利用Attribute表明需要导出的字段和文件名
2、利用C#的反射机制,遍历选择的所有文件,找到需要导出的List,并且解析需要导出的泛型类,根据Attribute将其导出。

特性定义
[System.AttributeUsage(System.AttributeTargets.Field, AllowMultiple = false)]  
public class ExportToCSV : System.Attribute  
{  
    public string property_name;  
    public ExportToCSV(string p_name)   
    {  
        property_name = p_name;  
    }  
}  
[System.AttributeUsage(System.AttributeTargets.Field, AllowMultiple = false)]  
public class ExportList : System.Attribute  
{  
    public string file_name;  
    public ExportList(string f_name)   
    {  
        file_name = f_name;  
    }  
}  

编辑器扩展
using System.Collections;  
using System.Collections.Generic;  
using UnityEngine;  
using UnityEditor;  
using System.Reflection;  
using System.Reflection.Emit;  
using System.IO;  
public class ExportScriptableObjectToCSV : MonoBehaviour {  
    private static Dictionary<string, List<string>> output_buffer = new Dictionary<string, List<string>>();  
    [MenuItem("Custom Scriptable Asset/Configs/Export Select ConfigFiles")]  
    public static void ExportAssetsToCSVs()  
    {  
        Object [] all_select = Selection.objects;  
        Debug.Log(" All select count is " + all_select.Length);  
        output_buffer.Clear();  
        foreach (var source in all_select)   
        {  
            ScriptableObject so = (ScriptableObject)source;  
            if (so != null)   
            {  
                ExportToCSV(so);  
            }  
        }  
    }  
    static void ExportToCSV( object source )   
    {  
        List<string> export_lines = new List<string>();  
        foreach (FieldInfo fieldinfo in source.GetType().GetFields())  
        {  
            if (fieldinfo.FieldType.IsGenericType)  
            {  
                object[] attributes = fieldinfo.GetCustomAttributes(typeof(ExportList), false);  
                foreach (var attribute_obj in attributes)  
                {  
                    if (attribute_obj is ExportList)  
                    {  
                        ExportList export_list = (ExportList)attribute_obj;  
                        string file_name = export_list.file_name;  
                        output_buffer[file_name] = new List<string>();  
                        //retrive list object;  
                        object list_object = fieldinfo.GetValue(source);  
                        int item_count = (int)(fieldinfo.FieldType.GetProperty("Count").GetValue(list_object, null));  
                        for (int i = 0; i < item_count; i++)  
                        {  
                            object listItem = fieldinfo.FieldType.GetProperty("Item").GetValue(list_object, new object[] { i });  
                            if (i == 0)   
                            {  
                                ProcessTitle(listItem, file_name);  
                            }  
                            ProcessValue(listItem, file_name);  
                        }  
                    }  
                }  
            }  
        }  
        foreach (var list in output_buffer)   
        {  
            Debug.Log("Writing " + list.Key + "...");  
            StreamWriter sw = new StreamWriter("Assets/Resources/Config/CSV/" + list.Key );  
            foreach (var item in list.Value)   
            {  
                sw.WriteLine(item);  
            }  
            sw.Flush();  
            sw.Close();  
            AssetDatabase.Refresh();  
        }  
    }  
    static void ProcessTitle( object target, string file_name )   
    {  
        System.Type this_type = target.GetType();  
        FieldInfo[] fields = this_type.GetFields();  
        string title = "";  
        foreach (var field in fields)  
        {  
            object[] attributes = field.GetCustomAttributes(typeof(ExportToCSV), false);  
            foreach (var obj in attributes)  
            {  
                ExportToCSV etc = (ExportToCSV)obj;  
                if (etc != null)  
                {  
                    title += etc.property_name + ",";  
                }  
            }  
        }  
        title = title.Substring(0, title.Length - 1);  
        output_buffer[file_name].Add(title);          
    }  
    static void ProcessValue( object target, string file_name )   
    {  
        System.Type this_type = target.GetType();  
        FieldInfo[] fields = this_type.GetFields();  
        string field_string = "";  
        foreach (var field in fields)  
        {  
            object[] attributes = field.GetCustomAttributes(typeof(ExportToCSV), false);  
            foreach (var obj in attributes)  
            {  
                ExportToCSV etc = (ExportToCSV)obj;  
                if (etc != null)  
                {  
                    string val = field.GetValue(target).ToString();  
                    field_string += val + ",";  
                }  
            }  
        }  
        field_string = field_string.Substring(0, field_string.Length - 1);  
        output_buffer[file_name].Add(field_string);  
    }  
}  

示例代码:
public class HeadImageConfig : ScriptableObject  
{  
    [System.Serializable]  
    public class HeadImageSet  
    {  
        [ExportToCSV("image_id")]  
        public int head_image_id;  
        [ExportToCSV("unlock_level")]  
        public int unlock_level;  
        [ExportToCSV("image_name")]  
        public string head_image_name = "long life mao";  
        public Sprite head_image;  
        public bool under_development = false;  
    }  
    [ExportList("s_head_image.csv")]  
    public List<HeadImageSet> head_images = new List<HeadImageSet>();  
来自:http://blog.csdn.net/WangHaoDiablo/article/details/69942710

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论