废话不多说,先上地址:
源码:https://github.com/RickJiangShu/ConfigManager
范例工程:https://github.com/RickJiangShu/ConfigManager-Example
引言
1、您是否需要在项目中使用Txt、Excel等表格配置?
2、您是否还在一行行写配置解析代码?
3、您是否担心运行时解析速度?
使用方法
1、新建一个txt文件并用电子表格软件打开编辑,最后也要保存成txt格式的哦。
2、编辑器:
点击菜单栏"Window/Config Manager";
设置对应的输入/输出路径;
点击Output。
其对应的路径:
Source Folder:存放配置文件
Config Output:存放根据配置文件自动编码的脚本
Asset Output:存放asset格式的配置文件
3、运行时:
调用反序列化接口;
使用配置文件。
SerializableSet set = Resources.Load
Deserializer.Deserialize(set);
/* 与加载解耦,不依赖加载方式
AssetBundle bundle = AssetBundle.LoadFromFile(Application.streamingAssetsPath + "/config.ab");
set = bundle.LoadAsset("SerializableSet");
Deserializer.Deserialize(set);
*/
MonsterConfig monsterCfg = MonsterConfig.Get(210102)
print(monsterCfg.name);
例:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class test : MonoBehaviour {
//自动生成的序列化设置类
SerializableSet set;
// Use this for initialization
void Start () {
set = Resources.Load ("SerializableSet");
Deserializer.Deserialize (set); //自动生成的资源解析类
Resources.UnloadUnusedAssets ();//卸载限制资源
float startTime = Time.realtimeSinceStartup;
Debug.Log (Time.realtimeSinceStartup - startTime+"s");
careerAttrConfig carrer1 = careerAttrConfig.Get (1);
Debug.Log ("配置文件:"+carrer1.name+" 力量"+carrer1.force);
}
// Update is called once per frame
void Update () {
}
}
设计思路
1、自动生成解析类
项目中经常需要用到策划配置,而一个策划配置需要写一个解析类去解析,这样浪费了大量的时间且容易出错。
因此,我觉得可以写一个自动生成解析类的工具。
2、编辑器下解析
通常解析工作是放在运行时,即加载一个文本文件之后再进行解析这个文本。这样在数据量巨大的时候,解析速度堪忧。
因此,我想把大量的解析工作放在编辑器下去处理。
**流程图
整个流程如上图所示,所以整个思路可以分为以下四个部分:解析、反射、序列化和反序列化
解析
- 按“分隔符”与“换行符”将表格切割成“行x列”的字符串矩阵,关键代码如下:
public static string[,] Content2Matrix(string config, string sv, string lf, out int row, out int col)
{
config = config.Trim();//清空末尾的空白
//分割
string[] lines = Regex.Split(config, lf);
string[] firstLine = Regex.Split(lines[0], sv, RegexOptions.Compiled);
row = lines.Length;
col = firstLine.Length;
string[,] matrix = new string[row, col];
//为第一行赋值
for (int i = 0, l = firstLine.Length; i < l; i++)
{
matrix[0, i] = firstLine[i];
}
//为其他行赋值
for (int i = 1, l = lines.Length; i < l; i++)
{
string[] line = Regex.Split(lines[i], sv);
for (int j = 0, k = line.Length; j < k; j++)
{
matrix[i, j] = line[j];
}
}
return matrix;
}
2.从矩阵中取出相应的字符,替换自定义模板中的变量并写入文件,关键代码如下:
string idType = ConfigTools.SourceType2CSharpType(src.matrix[1, 0]);
string idField = src.matrix[2, 0];
//属性声明
string declareProperties = "";
for (int x = 0; x < src.column; x++)
{
string comment = src.matrix[0, x];
string csType = ConfigTools.SourceType2CSharpType(src.matrix[1, x]);
string field = src.matrix[2, x];
string declare = string.Format(templete2, comment, csType, field);
declareProperties += declare;
}
//替换
content = content.Replace("/*ClassName*/", src.configName);
content = content.Replace("/*DeclareProperties*/", declareProperties);
content = content.Replace("/*IDType*/", idType);
content = content.Replace("/*IDField*/", idField);
//写入
ConfigTools.WriteFile(outputPath, content);
反射
上面解析出了C#文件和一个SerializableSet.cs,接下来将通过反射特性实例化一个SerializableSet对象,关键代码如下:
public static object Serialize(List
序列化
最后就是使用Unity API创建Asset文件,关键代码如下:
UnityEngine.Object set = (UnityEngine.Object)Serializer.Serialize(sources);
string o = cache.assetOutputFolder + "/" + assetName;
AssetDatabase.CreateAsset(set, o);
生成的文件如下:
反序列化
因为要在运行时使用,所以反序列化的代码没有使用反射(效率低)。而是在解析的过程中解析出一个反序列化文件,生成的代码如下:
public class Deserializer
{
public static void Deserialize(SerializableSet set)
{
for (int i = 0, l = set.Equips.Length; i < l; i++)
{
EquipConfig.GetDictionary().Add(set.Equips[i].EquipId, set.Equips[i]);
}
for (int i = 0, l = set.EquipCSVs.Length; i < l; i++)
{
EquipCSVConfig.GetDictionary().Add(set.EquipCSVs[i].EquipId, set.EquipCSVs[i]);
}
}
}
最后,直接调用相应的Config.Get(id)即可,效果如下:
转自:http://www.manew.com/thread-105598-1-1.html
作者:RickJiangShu