Unity热更新系列之AssetBundle(3) ——资源文件 xml 清单的生成与读取
2018-04-03 16:51
956 查看
当我们想要进行游戏资源热更新时,需要知道哪些资源文件需要进行热更新,
而最常见的做法就是使用一个文件记录每一个资源文件的version信息。
在玩家每次登陆游戏时,获取资源服务器上的version文件,
将其与本地文件进行对比,从而筛选出需要热更新的资源进行下载。
这里我们使用 xml 格式的文件用来处理这些信息。
我这里设计的version文件结构如下,首先是版本号,可以用来获取玩家当前的资源版本号。
接下来是一系列的资源信息列表 ,其中
name:该资源的 AssetBundle name,用来拼接该资源的下载路径(url = 资源服务器地址 + name )。
size : 该文件字节数,用来热更新时统计所需更新资源的大小。
md5码 : 用来比对该资源是否发生过更改,如果同一个资源的 md5码 本地和服务器不一致
,则证明需要下载该资源,将其加入到热更新下载队列。
这个文件当然不可能每次都自己手动生成,这里提供一下生成该version.xml文件的代码和读取方式
生成:
这里我们在Assets同层级文件夹目录下操作,这是因为如果在 Assets路径下进行文件增加删除操作,
会触发Unity 的AssetDatabase 的刷新,重新加载这些新生成的文件,并生成 .meta文件。
我们在这里新建了一个资源文件夹,存放Android平台的有戏资源,
并在里面放置了若干图集资源的AssetBundle文件。
然后运行代码,生成相应的version.xml 。
加载就相对简单的多了,我们只需要将xml的文件结构通过一个类映射出来,
再使用XmlSerializer.Deserialize() 解析就好了。
而最常见的做法就是使用一个文件记录每一个资源文件的version信息。
在玩家每次登陆游戏时,获取资源服务器上的version文件,
将其与本地文件进行对比,从而筛选出需要热更新的资源进行下载。
这里我们使用 xml 格式的文件用来处理这些信息。
我这里设计的version文件结构如下,首先是版本号,可以用来获取玩家当前的资源版本号。
接下来是一系列的资源信息列表 ,其中
name:该资源的 AssetBundle name,用来拼接该资源的下载路径(url = 资源服务器地址 + name )。
size : 该文件字节数,用来热更新时统计所需更新资源的大小。
md5码 : 用来比对该资源是否发生过更改,如果同一个资源的 md5码 本地和服务器不一致
,则证明需要下载该资源,将其加入到热更新下载队列。
这个文件当然不可能每次都自己手动生成,这里提供一下生成该version.xml文件的代码和读取方式
生成:
/// <summary> /// 生成version.xml文件 /// </summary> /// <param name="xmlPaths"></param> /// [MenuItem("Build/生成verison.xml")] public static void CreateVersionXml() { string outputPath = Application.dataPath.Replace("Assets","") + "Android"; //xml声明 XmlDocument xml = new XmlDocument(); xml.AppendChild(xml.CreateXmlDeclaration("1.0", "UTF-8", null)); //生成根节点 xml.AppendChild(xml.CreateElement("Root")); //生成大版本号 XmlNode root = xml.SelectSingleNode("Root"); XmlElement verNode = xml.CreateElement("version"); //版本号这里写死,如有需要,自由赋值 verNode.InnerText = "2.0"; root.AppendChild(verNode); //创建res节点 XmlElement resNode = xml.CreateElement("res"); root.AppendChild(resNode); //选择所有需要打包的资源类型 string[] files = System.IO.Directory.GetFiles(outputPath, "*.*", SearchOption.AllDirectories).Where(t => (t.EndsWith(".unity3d"))).ToArray(); //为每一个文件生成相应的xml foreach (var file in files) { FileInfo fileInfo = new FileInfo(file); string name = fileInfo.FullName.Replace("\\", "/").Replace(outputPath + "/", ""); AddNodeToXML(xml, name, MD5File(file), fileInfo.Length); } //将xml文件写入res目录下 xml.Save(outputPath + @"/version.xml"); System.Diagnostics.Process.Start(outputPath, outputPath); } /// <summary> /// 计算md5码 /// </summary> /// <param name="file"></param> /// <returns></returns> private static string MD5File(string file) { try { FileStream fs = new FileStream(file, FileMode.Open); System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(fs); fs.Close(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } return sb.ToString(); } catch (System.Exception ex) { throw new System.Exception("md5file() fail, error:" + ex.Message); } } /// <summary> /// 添加节点 /// </summary> /// <param name="xml"></param> /// <param name="name"></param> /// <param name="md5Str"></param> /// <param name="length"></param> private static void AddNodeToXML(XmlDocument xml, string name, string md5Str, long size) { //获取根节点 XmlNode resNode = xml.SelectSingleNode("Root/res"); //添加元素 XmlElement element = xml.CreateElement("res"); element.SetAttribute("name", name); element.SetAttribute("size", size.ToString()); element.InnerText = md5Str; resNode.AppendChild(element); }
这里我们在Assets同层级文件夹目录下操作,这是因为如果在 Assets路径下进行文件增加删除操作,
会触发Unity 的AssetDatabase 的刷新,重新加载这些新生成的文件,并生成 .meta文件。
我们在这里新建了一个资源文件夹,存放Android平台的有戏资源,
并在里面放置了若干图集资源的AssetBundle文件。
然后运行代码,生成相应的version.xml 。
加载就相对简单的多了,我们只需要将xml的文件结构通过一个类映射出来,
再使用XmlSerializer.Deserialize() 解析就好了。
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Xml.Serialization; using System.IO; public class xmlload : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (Input.GetKeyDown(KeyCode.D)) { string localversionPath = "file:///" + Application.dataPath.Replace("Assets", "") + "Android" + "/version.xml"; StartCoroutine(IELoadVersion(localversionPath)); } } public IEnumerator IELoadVersion(string path) { WWW www = new WWW(path); while (!www.isDone) { yield return null; } Stream stream = new MemoryStream(www.bytes); XmlSerializer xmlser = new XmlSerializer(typeof(CVersion)); CVersion localVersion = (CVersion)xmlser.Deserialize(stream); stream.Close(); www.Dispose(); foreach (var item in localVersion.element) { Debug.Log(item.name + " " + item.size + " " + item.md5); } } } /// <summary> /// version.xml的结构映射类 /// </summary> [XmlRoot("Root")] public class CVersion { [XmlElement("version")] public string version; [XmlArray("res"), XmlArrayItem("res")] public List<Version> element = new List<Version>(); } [XmlRoot("res")] public class Version { [XmlAttribute("name")] public string name; [XmlAttribute("size")] public string size; [XmlText()] public string md5; }
相关文章推荐
- unity 读取excel表 生成asset资源文件
- (安全系列二)apk反编译生成程序的源代码和图片、XML配置、语言资源等文件
- Unity热更新系列之AssetBundle(2) ——详述如何打AssetBundle资源
- 把项目中的xml文件的生成操作改为“嵌入的资源”,我在这个项目中怎么读取xml文件里的内容?
- (爱加密系列教程十)apk反编译生成程序的源代码和图片、XML配置、语言资源等文件
- Unity5系列资源管理AssetBundle——更新实现
- ResourceBundle.getBundle读取资源文件的路径
- [转] 生成/读取(反向更新数据库) Excel文件(示例代码下载)
- Java读取excel文件生成xml文档和JSON文档
- js生成xml文件及js读取xml文件,获得xml节点子节点的个数(同Extjs中树获得子结点个数)
- 使用Spring中Src下 -context.xml : 用资源文件夹保存数据库的链接信息 并在配置文件里读取
- wp7读取项目生成的资源(Resource)文件
- Unity Editor下选定单个资源文件打AssetBundle
- 生成/读取(反向更新数据库) Excel文件(示例代码下载)
- DOM模型的XML文件生成读取
- 生成/读取(反向更新数据库) Excel文件(示例代码下载)
- SpringBoot系列四:SpringBoot开发(改变环境属性、读取资源文件、Bean 配置、模版渲染、profile 配置)
- Android开发之Pull解析读取和生成XML文件
- Android下使用pull解析器生成XML文件、读取XML文件
- C# 读取 XML(嵌入资源文件)(转)