[游戏开发][Unity]Assetbundle加载篇(4)检查断点续传以及开始下载AB包

这篇具有很好参考价值的文章主要介绍了[游戏开发][Unity]Assetbundle加载篇(4)检查断点续传以及开始下载AB包。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

打包与资源加载框架目录

正文

AB包之前,要检查该AB包是否下载中断过,例如用户杀程序,卡死等情况。

前文有讲解过,下载AB包会先下载到临时文件夹,全部下载成功后,全部剪切到persistentDataPath沙盒目录中。

回顾一下之前的筛选机制,哪些AB包可以加入下载列表,其中并没有临时下载目录的判断。

该AB包数据是否加入列表要经过下面几个筛选

  1. 判断persistentDataPath沙盒目录是否存在该AB包,如果存在证明之前下载过,无需加入下载列表。

  1. 判断StreamingAsset目录中是否存在该AB包,如果存在证明打包时该AB包已经在包体里,无需加入下载列表。

  1. 如果该AB包的下载类型是游戏内下载,或者叫边玩边下,那么不需要在游戏启动热更时下载,无需加入下载列表

检查是否在临时下载目录中是否存在的代码如下

private IEnumerator CheckTempFileComplete(List<PatchElement> list, bool isPostCheck)
{
    PatchEventDispatcher.SendCheckDownloadedFileMd5();
    var sw = new Stopwatch();
    sw.Start();
    var buf = new byte[10240];
    this.totalDownloadSizeKB = 0;
    this.currentDownloadSizeKB = 0;
    this.currentDownloadCount = 0;
    using (var md5 = System.Security.Cryptography.MD5.Create())
    {
        foreach (var ele in list)
        {
            this.totalDownloadSizeKB += ele.SizeKB;
            string savePath = AssetPathHelper.MakeDownloadTempPath(ele.Name);
            if (!File.Exists(savePath))
            {
                //下载后的检查需要抛出异常,下载前的检查跳过不存在文件
                if (isPostCheck)
                {
                    PatchHelper.Log(ELogLevel.Error, $"[checking md5] file is not existed: {ele.Name}");
                    failedOnCheckDownload = true;
                    yield break;
                }
                else
                {
                    continue;
                }
            }
            
            using (var fs = new FileStream(savePath, FileMode.Open, FileAccess.Read))
            {
                int byteRead;
                md5.Initialize();
                while ((byteRead = fs.Read(buf, 0, buf.Length)) > 0)
                {
                    md5.TransformBlock(buf, 0, byteRead, null, 0);
                    if (sw.ElapsedMilliseconds > 250)
                    {
                        yield return null;
                        sw.Restart();
                    }
                }
                md5.TransformFinalBlock(buf, 0, 0);
                fs.Close();
                string localMd5 = BitConverter.ToString(md5.Hash).Replace("-", "");
                if (string.Equals(ele.MD5, localMd5, StringComparison.OrdinalIgnoreCase))
                {
                    //MotionLog.Log(ELogLevel.Log, StringFormat.Format("skip download existed file: {0}", savePath));
                    ele.SkipDownload = true;
                    this.currentDownloadSizeKB += ele.SizeKB;
                    this.currentDownloadCount++;
                }
                else if (isPostCheck)
                {
                    PatchHelper.Log(ELogLevel.Error, $"Web file md5 verification error : {ele.Name}");
                    PatchHelper.Log(ELogLevel.Error, $"local md5 is : {localMd5}");
                    PatchHelper.Log(ELogLevel.Error, $"md5 in manifest is : {ele.MD5}");
                    PatchEventDispatcher.SendWebFileMD5VerifyFailedMsg(ele.Name);
                    failedOnCheckDownload = true;
                    File.Delete(savePath);
                    yield break;
                }
            }
        }
    }
}

布尔值isPostCheck的作用是是否是二次检测,先不管它

按流程来走

  1. 检查该AB包是否在临时文件夹中存在,如果不存在则跳过

  1. 如果已存在,创建该临时下载文件的MD5,与下载清单中的MD5做对比

  1. 如果MD5对比一致,则标记该AB包数据为SkipDownload,同时标记下载数据长度,供UI显示

我们项目里目前的代码被人改了,我也有有点看不懂为何要用 md5.TransformBlock的方式

下面是一套生成MD5码的代码,加载文件,MD5CryptoServiceProvider会根据加载的stream生成hash,

readonly MD5CryptoServiceProvider _provider = new MD5CryptoServiceProvider();
public static string StreamMD5()
{
    using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
    {
        byte[] hashBytes = _provider.ComputeHash(stream);
        return ToString(hashBytes);
    }
}
private static string ToString(byte[] hashBytes)
{
    var sb = new StringBuilder();
    foreach (var t in hashBytes)
    sb.Append(t.ToString("x2"));
    return sb.ToString();
}

首先要判断临时下载目录中是否存在该文件,如果没有,我们项目文章来源地址https://www.toymoban.com/news/detail-476842.html

private IEnumerator Download()
{
    // 计算下载文件的总大小
    totalDownloadCount = _patcher.DownloadList.Count;
    if (totalDownloadCount == 0)
    {
        _patcher.SwitchNext();
        yield break;
    }
    //先检查一遍temp目录有没有下载完的, 计算这次实际需要下载的个数和size
    yield return CheckTempFileComplete(_patcher.DownloadList, false);

    // 开始下载列表里的所有资源
    PatchHelper.Log(ELogLevel.Log, $"Begine download web files : {totalDownloadCount-currentDownloadCount}");
    PatchEventDispatcher.SendPatchStatesChangeMsg(EPatchStates.DownloadWebFiles);
    var startTime = Time.realtimeSinceStartup;
    var newDownloaded = new List<PatchElement>(_patcher.DownloadList.Count);
    foreach (var element in _patcher.DownloadList)
    {
        if (element.SkipDownload) continue;
        newDownloaded.Add(element);
    }

    if (useMultiRequest)
    {
        yield return DownloadWithMultiTask(newDownloaded);
    }
    else
    {
        yield return DownloadWithSingleTask(newDownloaded);
    }
    if (failedOnDownload)
    {
        yield break;
    }
    MotionLog.Log(ELogLevel.Log, $"<color=#ff0000>Downloading {newDownloaded.Count} files cost {Time.realtimeSinceStartup-startTime} sec.</color>");
    //全部下载完成后把这次新下载的文件再校验一遍,如果有文件失败就退出
    yield return CheckTempFileComplete(newDownloaded, true);
    if (failedOnCheckDownload)
    {
        yield break;
    }
    
    if (_patcher.MiniAndroid)
    {
        var fileCount = _patcher.DownloadList[0].Version; // tricky storing filecount in field [version]
        var zipFileName = _patcher.DownloadList[0].Name;
        yield return DecompressInitPack(zipFileName, fileCount);
    }
    else
    {
        yield return DeployDownloadFiles();
    }

    // 最后清空下载列表
    _patcher.DownloadList.Clear();
    _patcher.SwitchNext();
}

到了这里,关于[游戏开发][Unity]Assetbundle加载篇(4)检查断点续传以及开始下载AB包的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [游戏开发][Unity]Assetbundle打包篇(2)打包资源配置篇

    打包与资源加载框架目录 可视化配置的方式有很多种,Json、XML、以及Unity内置的ScriptableObject序列化 配置文件里要有哪些内容呢,很显然,最重要的就是目标文件路径,其次是权重类型,权重类型有:必要打包型、被引用打包型、忽略类型。为何会有忽略类型呢,是因为我们

    2024年02月09日
    浏览(43)
  • [游戏开发][Unity]Assetbundle下载篇(7)获取运行时(边玩边下)下载列表

    打包与资源加载框架目录 啥是运行时下载清单?现在大多数手游都会有一个边玩边下功能,会提示用户是否开启下载,要XXX流量,如果你下载完了,可能还会有奖励。   疑问:为何要有边玩边下功能? 解答:为了发包的包体小,并且是越小越好! 我们的游戏想要赚钱,第一

    2024年02月08日
    浏览(46)
  • [游戏开发][Unity]Assetbundle打包篇(5)使用Manifest二次构建资源索引

    打包与资源加载框架目录 正文开始前,先把打包代码放过来,请注意,前面的代码已省略,自己去对比前面的文章。本篇文章从第一次执行打包代码开始。 第一次调用BuildPipeline.BuildAssetBundles打包API后(详见代码第七行),会返回AssetBundleManifest的引用, 【疑问】: BuildPipe

    2024年02月03日
    浏览(36)
  • [游戏开发][Unity]Assetbundle下载篇(1)热更前准备与下载AB包清单

    打包与资源加载框架目录 热更流程都不是固定的,每个人写的状态机也有所差别,但是一些必要步骤肯定不可能少,例如下载清单,对比版本,下载AB包,标记下载完成。我接下来的每一篇文章都是下载AB包的重要步骤,大概率是不能省略的。 检查沙盒路径是否存在 检查下载

    2024年02月15日
    浏览(40)
  • 【Unity】AssetBundle加载与卸载

    需要注意的是同一个ab包一次只能加载一个,不可以同时加载, 报错: The AssetBundle \\\'xxxxx\\\' can\\\'t be loaded because another AssetBundle with the same files is already loaded. 如果AB包已经加载过则先进行卸载: 1、卸载全部的目前没有使用的资源: Resources.UnloadUnusedAssets() 2、卸载 AssetBundle 释放其

    2024年04月25日
    浏览(31)
  • Unity-AssetBundle Browser 打包和加载

    进入unity手册中,搜素 Unity Asset Bundle Browser 工具,选择你使用的版本号,根据显示出的操作进行资源导入即可。 注:有的版本可能没有资源链接,可以百度一下有很多。 1、制作预制体(省略)  2、选择一个预制体,在Inspector窗口下方,设置预制体的ab包名(包名只能为小写字

    2024年04月13日
    浏览(38)
  • Unity AssetBundle批量打包、加载(场景、Prefab)完整流程

    1、文章介绍 2、具体思路和写法         (1)AB包的打包         (2)AB包的加载         (3)AB包卸载 3、结语 本篇博客主要起记录和学习作用,简单的介绍一下AB包批量的打包和加载AB包的方式,若各位同学有幸看到本篇博客,希望能够对你有所帮助。 (1)

    2024年02月04日
    浏览(43)
  • Unity的AssetBundle系统来动态加载FBX模型

    在Unity中,可以使用C#脚本和Unity的AssetBundle系统来动态加载FBX模型。以下是一个简单的示例,演示如何动态加载FBX模型: 准备FBX模型 首先,准备一个或多个FBX模型,并将它们导入到Unity项目中。确保每个FBX模型都有一个独立的游戏对象,并且已经被正确地设置为“Static”或“

    2024年02月06日
    浏览(44)
  • 【Unity】AssetBundle资源异步加载以及AB包卸载

    以下代码是基于上一篇文章《AssetBundle资源同步加载》的代码新增了异步加载和AB包卸载功能,有兴趣的同学可以去看看我的上一篇文章。 由于异步加载需要配合协程进行功能开发,所以我对之前封装的AB包资源加载管理器进行修改,改为继承MonoBehaviour的单例模式。 主要修改

    2023年04月08日
    浏览(38)
  • Unity中使用AssetBundle打包与加载的注意事项

    一、使用AssetBundle进行打包与加载 个人觉得可以参考以下两篇博客,这个网上相关教程很多,还不明白的可以去百度,或者给我留言。 Unity 打包与加载AssetBundle(加载对应的依赖) Unity中的AssetBundle 二、使用AssetBundle进行加载的时候注意事项: 注意事项一:AssetBundle名字和设置

    2024年02月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包