做unity 项目也有一段时间了,从unity项目开发和学习中也遇到了很多坑,并且也从中学习到了很多曾经未接触的领域。项目中的很多功能模块,从今天开始把自己的思路和代码奉上给学渣们作为一份学习的资料。如果学长们看到哪里写的不好欢迎吐槽并给予更好的解决方案。好了话也不多说了今天给大家亮出的是excel 数据解析和在unity项目中的应用。
*导入excel,解析xml,生成c#数据表,生成asset数据文件
*原理 在导入xml文件的时候通过XmlReader读取xml文件
*把需要的内容按照读取的顺序保存,然后在生成key,最后生成key,value格式,然后自己手动定义要保存的内容数据格式最后通过自定义的数据格式生成数据文件
注:ExcelControl 这个类必须放在Editor目录下
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Xml;
using System;
using System.Collections.Generic; public class ExcelControl : AssetPostprocessor
{
static string FILE_PATH = "Assets\\Data\\"; /** 在导入所有资源之后 */
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths)
{ string excelPath = "";
for (int i = ; i < importedAssets.Length; i++)
{
/** 拦截Assets/Excel目录下面所有.xml文件进行解析 */
excelPath = importedAssets[i];
if (excelPath.Contains(".xml"))
{
ReadXml(excelPath);
Debug.Log("Excel import asset path : " + excelPath);
}
}
} static void ReadXml(string xmlPath)
{
/** 读取xml 文件 */
XmlReader xReader = null;
try
{
xReader = XmlReader.Create(xmlPath);
}
catch (Exception e)
{
Debug.LogError("Read Excel Error! Path = " + xmlPath);
}
if (xReader == null)
{
return;
} /** 保存所有数据到表中 */
List<xmlSheetList> xmlDataList = new List<xmlSheetList>();
xmlSheetList xsl = null; /** 记录每个节点的开始 */
bool sheetBegin = false;
bool rowBegin = false;
bool cellBegin = false;
bool dataBegin = false; /** 行数 */
int rowNum = ;
/** 列数 */
int cellNum = ;
/** 计数器 */
int num = ;
while (xReader.Read())
{
string name = xReader.Name; if (name == "Worksheet")
{
/** 开始 */
if (xReader.NodeType == XmlNodeType.Element)
{
sheetBegin = true;
/** xmlSheet */
xsl = new xmlSheetList();
xsl.Clear();
}
/** 结束 */
else if (xReader.NodeType == XmlNodeType.EndElement)
{
sheetBegin = false;
xmlDataList.Add(xsl);
}
}
else if (name == "Row")
{
/** 开始 */
if (xReader.NodeType == XmlNodeType.Element)
{
rowBegin = true;
rowNum++;
}
/** 结束 */
else if (xReader.NodeType == XmlNodeType.EndElement)
{
rowBegin = false;
}
}
else if (name == "Cell")
{
/** 开始 */
if (xReader.NodeType == XmlNodeType.Element)
{
cellBegin = true;
if (rowNum == )
{
cellNum++;
}
if (!string.IsNullOrEmpty(xReader.GetAttribute("ss:Index")))
{ Debug.LogError(string.Format("xml read error! may be empty! : {0} Row = {1} Cell = {2}.", xmlPath, (int)(num / cellNum), ((num % cellNum) + )));
return;
}
}
/** 结束 */
else if (xReader.NodeType == XmlNodeType.EndElement)
{
cellBegin = false;
}
}
else if (name == "Data")
{
/** 开始 */
if (xReader.NodeType == XmlNodeType.Element)
{
dataBegin = true;
}
/** 结束 */
else if (xReader.NodeType == XmlNodeType.EndElement)
{
dataBegin = false;
}
}
else {
/** 过滤数据 */
if (sheetBegin && rowBegin && cellBegin && dataBegin)
{
num++;
if (xsl != null)
{
xsl.Add(xReader.Value);
}
}
}
}
int an = xmlDataList.Count; //生成key列表
List<string> keys = new List<string>();
for (int i = ; i < xmlDataList.Count; i++)
{
for (int k = ; k < cellNum; k++)
{
if (k < cellNum)
{
keys.Add(xmlDataList[i].sheetList[]);
// 删除原始列表中key的数据
xmlDataList[i].sheetList.RemoveAt();
}
else {
break;
}
}
} // 创建key 和 value 结构
List<Row> rowList = new List<Row>();
int nb = ;
for (int k = ; k < xmlDataList.Count; k++)
{
nb = xmlDataList[k].sheetList.Count / cellNum;
for (int i = ; i < nb; i++)
{
Row row = new Row();
row._key = keys;
for (int j = ; j < cellNum; j++)
{
row._cells.Add(xmlDataList[k].sheetList[]);
xmlDataList[k].sheetList.RemoveAt();
}
rowList.Add(row);
}
}
/** 创建资源 */
CreatXmlListAsset(rowList, xmlPath);
} /** 生成数据文件 */
static void CreatXmlListAsset(List<Row> rl, string xmlPath)
{
if (xmlPath.Contains("excel.xml"))
{
//新生成的数据
ExcelDataList dataList = null; //检查是否已经声称过了数据表
UnityEngine.Object oldFile = AssetDatabase.LoadAssetAtPath(xmlPath, typeof(ExcelDataList));
bool newFile = false;
if (oldFile)
{
dataList = oldFile as ExcelDataList;
}
else {
dataList = new ExcelDataList();
newFile = true;
}
//清空已有数据
dataList.Datalist.Clear(); //生成数据
for (int i = ; i < rl.Count; i++)
{
ExcelData newData = new ExcelData();
Row data = rl[i];
newData.id = GetInt(data["ID"]);
newData.name = data["Name"];
dataList.Datalist.Add(newData);
} // 创建数据文件
if (newFile)
{
AssetDatabase.CreateAsset(dataList, FILE_PATH + "ExcelDataList.asset");
}
else {
EditorUtility.SetDirty(dataList);
}
}
} static int GetInt(string data)
{
float val = ;
try
{
val = float.Parse(data);
}
catch (Exception e)
{
Debug.LogError(e.Message + " data[" + data + "]");
}
return Mathf.RoundToInt(val);
} static float GetFloat(string data)
{
float val = ;
try
{
val = float.Parse(data);
}
catch (Exception e)
{
Debug.LogError(e.Message + " data[" + data + "]");
}
return val;
} static bool GetBool(string data)
{
int val = ;
try
{
val = int.Parse(data);
}
catch (Exception e)
{
Debug.LogError(e.Message + " data[" + data + "]");
}
return val == ? false : true;
}
} /** xmlsheel所有字符串数据 */
public class xmlSheetList
{
public List<string> sheetList = new List<string>(); public void Add(string str)
{
sheetList.Add(str);
} public void Clear()
{
sheetList.Clear();
}
} /** xml (key, Value) Cell */
public class Row
{
public List<string> _cells = new List<string>();
public List<string> _key = new List<string>(); public string this[string key]
{
get
{
string val = "";
int pos = _key.IndexOf(key);
if (pos < || pos >= _cells.Count)
{
Debug.LogError("can't find the value of the key:[" + key + "]");
}
else {
val = _cells[pos];
}
return val;
}
}
}
using UnityEngine;
using System.Collections;
using System.Collections.Generic; [System.Serializable]
public class ExcelData {
public string name = "";
public int id = ;
}
public class ExcelDataList : ScriptableObject {
public List<ExcelData> Datalist = new List<ExcelData>();
}
ExcelData 自定义的数据格式根据项目需求 支持原创,转载请注明作者出处我的博客http://home.cnblogs.com/u/fastHro/