예제 #1
0
    /// <summary>
    /// 发布资源
    /// </summary>
    private static void DoBuildPublish(BuildTarget target, string resVersion, bool isNewAssets, string channel)
    {
        string rootPath    = GetABRootPath(target, channel);
        string publishPath = string.Format("{0}/PublishAssetBundles/", rootPath);
        string abPath      = string.Format("{0}/AssetBundles/", rootPath);
        string patchPath   = string.Format("{0}/PatchAssetBundles/", rootPath);
        string encryptPath = string.Format("{0}/EncryptAssetBundles/", rootPath);

        // 如果需要重新打包资源则删除原来的版本文件
        if (isNewAssets)
        {
            FileMgr.DeleteDirectory(abPath);
        }

        // ab路径是否存在,不存在则创建一个
        DirectoryInfo abInfo = new DirectoryInfo(abPath);

        if (!abInfo.Exists)
        {
            abInfo.Create();
        }

        // 确保目录存在
        FileMgr.DeleteDirectory(encryptPath);
        FileMgr.CreateDirectory(encryptPath);
        FileMgr.DeleteDirectory(publishPath);
        FileMgr.CreateDirectory(publishPath);
        FileMgr.DeleteDirectory(patchPath);
        FileMgr.CreateDirectory(patchPath);

        BuildAssetBundleOptions opt =
            BuildAssetBundleOptions.DeterministicAssetBundle |      // 保证同样的资源多次打包出的assetbundle相同
            BuildAssetBundleOptions.UncompressedAssetBundle;        // 不压缩资源,我们会压缩,然后在目标平台解压缩,最后使用的是没有压缩的资源,保证资源快速加载

        // AssetBundle打包,Unity5.x之后都是用这个方法打包,而且还会自动生成依赖关系
        AssetBundleManifest manifest = BuildPipeline.BuildAssetBundles(abPath, opt, target);

        // 载入旧版本树
        CsvFile oldVersionCsv = LoadVersion(abPath);

        // 生成资源映射表
        GenResourceDictFile(abPath, manifest);

        //// 加密ab资源包
        DoEncryptAssetBundle(encryptPath, abPath, manifest);

        // 收集需要发布的ab资源包
        Dictionary <string, string> newABVersion = DoCollectNewABVersion(encryptPath, manifest);

        // 资源大小映射表
        Dictionary <string, List <object> > versionItemInfo = new Dictionary <string, List <object> >();

        // 是否需要更新标识
        bool isABChanged = false;

        byte[] unzipBuf;
        byte[] buf;

        // 发布资源
        foreach (string abName in newABVersion.Keys)
        {
            // 获取旧版本信息
            CsvRow data = oldVersionCsv.FindByKey(abName);

            if ((data != null) && string.Equals(data.Query <string>("md5"), newABVersion[abName]))
            {
                // 添加到列表中
                versionItemInfo.Add(abName, new List <object>()
                {
                    newABVersion[abName], data.Query <int>("unzip_size"), data.Query <int>("zip_size")
                });
                continue;
            }

            // 标识数据已经变化了
            isABChanged = true;

            // 取得未压缩大小
            unzipBuf = File.ReadAllBytes(string.Format("{0}{1}", encryptPath, abName));
            if (unzipBuf.Length == 0)
            {
                NIDebug.Log(string.Format("读取{0}{1}失败!", encryptPath, abName));
                continue;
            }

            NIEditorUtility.Zip(new string[] { string.Format("{0}{1}", encryptPath, abName) }, string.Format("{0}{1}_{2}.zip", publishPath, abName, newABVersion[abName]));

            // 读取文件
            buf = File.ReadAllBytes(string.Format("{0}{1}_{2}.zip", publishPath, abName, newABVersion[abName]));
            if (buf.Length == 0)
            {
                NIDebug.Log(string.Format("读取{0}{1}失败!", publishPath, abName));
                continue;
            }

            // 添加到列表中
            versionItemInfo.Add(abName, new List <object>()
            {
                newABVersion[abName], unzipBuf.Length, buf.Length
            });
        }

        // 如果ab资源没有变化, 不处理
        if (isABChanged)
        {
            string resourceDictPath = string.Format("{0}{1}", encryptPath, "resource_dict.bytes");

            // 发布资源到发布资源目录
            string md5 = NIEditorUtility.GetFileMD5(resourceDictPath);

            // 取得未压缩大小
            unzipBuf = File.ReadAllBytes(string.Format("{0}{1}", encryptPath, "resource_dict.bytes"));
            if (unzipBuf.Length == 0)
            {
                NIDebug.Log(string.Format("读取{0}{1}失败!", encryptPath, "resource_dict.bytes"));
                return;
            }

            NIEditorUtility.Zip(new string[] { string.Format("{0}{1}", encryptPath, "resource_dict.bytes") }, string.Format("{0}{1}_{2}.zip", publishPath, "resource_dict.bytes", md5));

            // 读取文件
            buf = File.ReadAllBytes(string.Format("{0}{1}_{2}.zip", publishPath, "resource_dict.bytes", md5));
            if (buf.Length == 0)
            {
                NIDebug.Log(string.Format("读取{0}{1}失败!", publishPath, "resource_dict.bytes"));
                return;
            }

            // 添加到列表中
            versionItemInfo.Add("resource_dict.bytes", new List <object>()
            {
                md5, unzipBuf.Length, buf.Length
            });
        }

        bool isPatchChanged = false;

        Dictionary <string, string> abPatchDic = new Dictionary <string, string>();

        // 生成压缩patch文件
        Dictionary <string, string> newPatchVersion = GenPatchFiles(patchPath, encryptPath, versionItemInfo, ref abPatchDic);

        // 发布资源
        foreach (string patchName in newPatchVersion.Keys)
        {
            // 获取旧版本信息
            CsvRow data = oldVersionCsv.FindByKey(patchName);

            if ((data != null) && string.Equals(data.Query <string>("md5"), newPatchVersion[patchName]))
            {
                versionItemInfo.Add(patchName, new List <object>()
                {
                    data.Query <string>("md5"), 0, data.Query <int>("zip_size")
                });
                continue;
            }

            // 标识数据已经变化了
            isPatchChanged = true;

            string filePath = string.Format("{0}{1}_{2}.zip", patchPath, patchName, newPatchVersion[patchName]);

            // 读取文件
            buf = File.ReadAllBytes(filePath);
            if (buf.Length == 0)
            {
                NIDebug.LogError(string.Format("读取{0}失败!", filePath));
                continue;
            }

            versionItemInfo.Add(patchName, new List <object>()
            {
                newPatchVersion[patchName], 0, buf.Length
            });

            File.Copy(filePath, string.Format("{0}{1}_{2}.zip", publishPath, patchName, newPatchVersion[patchName]), true);
        }

        // 有变化重新生成版本文件
        if (isABChanged || isPatchChanged)
        {
            // 将资源版本添加到列表中
            versionItemInfo.Add("res_version", new List <object>()
            {
                resVersion, 0, 0
            });

            // 生成某个目录下的版本控制文件
            GenVersionFile(abPath, publishPath, versionItemInfo, abPatchDic);
        }

        // 标识Build AssetBundle OK
        NIDebug.Log("生成AssetBundle完成");

        // 刷新编辑器
        AssetDatabase.Refresh();
    }