Assetbundle(二)热更新方案设计

上一篇:Assetbundle(一)引用计数方案设计

下一篇:AssetBundle(三) 场景和Navmesh的加载

先给出流程图,再解释过程

Assetbundle(二)热更新方案设计_第1张图片

 

   游戏打包,安装到手机上后,沙盒目录下是空的,StreamingAssets目录下应该有三个bundle的配置文件,一个版本文件和实际的bundle若干。

StreamingAssets目录  
AssetBundleManifest unity自动生成
asset-bundle 资源和Bundle对应关系(打包脚本生成)
bundle-hash 每个bundle的哈希值(打包脚本生成)
GameVersion 打包前生成的版本文件
bundle-1 实际的bundle
bundle-2  

第一步

如果是首次安装,沙盒目录为空;如果大版本更新,那么StreamingAssets目录下的版本文件版本号会大于沙盒目录版本号。因此沙盒目录内没有版本文件或者版本号小于包内目录,那么要将包内的bundle配置文件和版本文件Copy到沙盒目录。后续步骤中和服务器对比都用沙盒目录的文件了。以下是用WWW接口的Bundle 函数实现bundle的从包内Copy到沙盒目录。当然,也可以写单独写插件实现从包内拷贝。

        IEnumerator CoCopyAssetBundle(string source, string dest, System.Action callback)
        {
            using (WWW www = new WWW(source))
            {
                while(!www.isDone)
                {
                    if(!string.IsNullOrEmpty(www.error))
                    {
                        Logger.LogWarp.LogError(www.error);
                        yield break;
                    }
                    else
                    {
                        yield return www;
                    }
                }

                File.WriteAllBytes(dest, www.bytes);
                if (callback != null)
                {
                    callback(dest);
                }
            }
        }

第二步

从服务器下载版本文件,如果沙盒目录内原有版本号小于服务器下载版本号,那么从服务器下载三个bundle配置文件。

第三步

根据服务器下载的bundle-hash和沙盒目录的bundle-hash对比,从服务器下载服务器有而本地没有的bundle,或者都有,只是hash不相同的bundle。这一步可以用HashSet轻松实现。

额外说明

1.下载没有用WWW接口,一是不太好用,二是效率不太好。因此单独实现了一个多线程版本的的http下载,支持单个文件下载和多个文件下载。下面是该源码下载链接:

Http文件下载实现

2.关于用于测试用http文件下载服务器的搭建,推荐用python。原因是配置很简单,没有额外的代码,只需要安装好python + windows dos里敲一行命令即可。详见以下链接:

用Python搭建http文件下载服务器

3.下载的bundle是需要做md5检查的,因此建议bundle-hash里记录MD5值。因为MD5可以同时作为差异对比,提供下载bundle的依据,也能用于下载的完整性检查。随便说一句,bundle接口中取出的hash并不是md5。MD5在C#中很好实现,基本上用系统的API就能完成。

        public static string FileMD5(string filename)
        {
            using (var md5 = MD5.Create())
            {
                using (var stream = File.OpenRead(filename))
                {
                    // Convert the byte array to hexadecimal string
                    byte[] hashBytes = md5.ComputeHash(stream);
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < hashBytes.Length; i++)
                    {
                        sb.Append(hashBytes[i].ToString("X2"));
                    }
                    return sb.ToString();
                }
            }
        }

编辑器环境下获取hash和crc的API如下

            uint crc;
            BuildPipeline.GetCRCForAssetBundle(path, out crc);
            Hash128 hash;
            BuildPipeline.GetHashForAssetBundle(path, out hash);

 

4.建议每次大版本更新后,清理一次沙盒目录下的文件。因为随着版本更新,必然有一些无用bundle文件还保留在沙盒目录。每次大版本更新就像一次新的开始,把沙盒目录清理成初始状态。

 

 

你可能感兴趣的:(Assetbundle(二)热更新方案设计)