您的位置:首页 > 移动开发 > Unity3D

Unity ScriptableObject 自动导出 .csv文件

2017-04-10 10:03 225 查看
ScriptableObject给客户端用是很好用的,但是,如果给服务器端用,却很麻烦,所以我写了一个自动导出工具,可以以很小的代价,将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>();


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  反射 特性 Unity Scriptab