客户端编辑器主要的作用是把配置文件(格式是Excel)序列化生成二进制文件,在游戏中进行加载使用。
通过对别的项目的编辑器的学习,了解到一种实现方式:
1.使用Flex生成桌面程序,利用as3xls操作Excel获得数据
2.生成前端的vo.cs和对应的xml,后端文件
3.生成C#的桌面程序
4.加载vo.cs,利用反射生成对应的对象
5.加载xml,把xml的值通过反射设置进对象中
6.通过序列化生成文件
通过这种实现方式,每次生成配置的时候,就需要操作两个工具,个人觉得不如直接使用C#桌面程序读取Excel。
1.生成C#桌面程序
2.使用Oledb读取读取Excel(C#读取Excel有几种方式,百度即可)
3.生成vo.cs文件
4.反射生成vo对象,设值对象
5.序列化
在实现以上步骤的过程中,碰到过了不少问题。
1.使用Oledb读取Excel,要同时考虑到.xls和.xlsx文件:
//2003(Microsoft.Jet.Oledb.4.0)
string strConn = string.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties=‘Excel 8.0;HDR=Yes;IMEX=1;‘", excelFilePath);
//2010(Microsoft.ACE.OLEDB.12.0)
string strConn = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=‘Excel 8.0;HDR=Yes;IMEX=1;‘", excelFilePath);
2.创建字符串保存vo.cs文件,然后使用反射根据字符串动态创建对象。
CSharpCodeProvider provider = new CSharpCodeProvidor(); //创建编译器
CompilerParameters paras = new CompilerParameters(); //设置编译参数
paras.ReferenceAssemblies.Add(“System.dll”);
paras.GenerateExecutable = false; //编译成exe还是dll
paras.GenerateInMemory = true; //是否写入内存,不写入内存就写入磁盘
CompilerResults result = provider.CompileAssembleyFromSource(paras, sourceCode(对象的字符串代码)); //编译代码
Assembly as = result.CompiledAssemble; //获得编译后的程序集
Object obj = as.CreateInstance(“com.game.vo.voName”);
3.通过反射把excel中的值设置进obj
4.把设值好的对象保存进ArrayList当中,对其进行序列化,并保存成 vo.bytes,这里之所以保存成.bytes,是为了在unity中加载(储存文件的扩展名以" .bytes"为结尾的二进制数据。Unity会把它们看成TextAsset来使用。):
public byte[] SerializeBinary(object request)
{
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter serializer = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
System.IO.MemoryStream memStream = new System.IO.MemoryStream();
serializer.Serialize(memStream, request);
return memStream.GetBuffer();
}
5.把生成好的vo.bytes以及vo.cs放到Unity3d项目中
6.使用Unity3d把vo.bytes文件打包成assetBundle文件 (这个步骤是对文件进行压缩,减少文件尺寸)
7.运行Unity3d项目,加载打包好的vo.assetBundle文件,加载成bytes:
string url = "http://www.mywebsite.com/mygame/assetbundles/vo.assetBundle"; IEnumerator Start () { // Start a download of the given URL WWW www = WWW.LoadFromCacheOrDownload (url, 1); // Wait for download to complete yield return www; // Load and retrieve the AssetBundle AssetBundle bundle = www.assetBundle; // Load the TextAsset object TextAsset txt = bundle.Load("myBinaryAsText", typeof(TextAsset)) as TextAsset; // Retrieve the binary data as an array of bytes byte[] bytes = txt.bytes; }
8.反序列化二进制得到配置数据,这里要注意一点就是前面生成的vo.cs文件必须放在com.game.vo目录下,否则反序列化会报找不对vo对象。
public object DeserializeBinary(byte[] buf)
{
System.IO.MemoryStream memStream = new MemoryStream(buf);
memStream.Position = 0;
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter deserializer =
new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
object newobj = deserializer.Deserialize(memStream);
memStream.Close();
return newobj;
}
9.完成。