06-03-YooAsset源码-Unity下载系统(DownloadSystem)
源码-下载系统DownloadSystem篇章06-源码深度-文件系统与下载模块阅读时间约 30 分钟前置知识了解 IFileSystem一、引言本章将深入解析 YooAsset 下载系统DownloadSystem的源码实现。DownloadSystem 是 YooAsset 热更新功能的核心负责从远程服务器下载资源到本地。深入理解 DownloadSystem 是掌握 YooAsset 热更新机制的关键。DownloadSystem 采用了 DownloadManager、DownloadTask、BundleDownloader 的分层架构支持并发下载、断点续传、错误重试等高级特性。本章将从源码层面深入解析 DownloadSystem 的实现。二、下载系统架构2.1 分层架构YooAsset 的下载系统采用三层架构下载系统架构 ├── DownloadManager下载管理器 │ ├── 全局下载管理 │ ├── 并发控制 │ └── 任务调度 ├── DownloadTask下载任务 │ ├── 单个 Package 的下载任务 │ ├── 子任务管理 │ └── 进度汇总 └── BundleDownloaderBundle 下载器 ├── 单个 Bundle 的下载 ├── HTTP 请求 └── 文件写入DownloadManager 详解DownloadManager 是下载管理器负责全局的下载管理。DownloadTask 详解DownloadTask 是下载任务封装了一个 Package 的所有 Bundle 下载。BundleDownloader 详解BundleDownloader 是 Bundle 下载器负责单个 Bundle 的实际下载。2.2 核心组件public class DownloadManager { public int DownloadMaxConcurrency { get; set; } 10; public int FailedTryAgain { get; set; } 3; public float Timeout { get; set; } 60f; private ListDownloadTask _allTasks new ListDownloadTask(); private ListDownloadTask _runningTasks new ListDownloadTask(); public DownloadTask CreateDownloadTask(ResourcePackage package, ListBundleInfo bundleInfos); public void StartDownload(DownloadTask task); public void StopDownload(DownloadTask task); } public class DownloadTask : AsyncOperationBase { public ListBundleDownloader Downloaders { get; } public long TotalSize { get; } public long DownloadedSize { get; } public float Progress { get; } public DownloadStatus Status { get; } } public class BundleDownloader { public BundleInfo BundleInfo { get; } public long DownloadedBytes { get; } public float Progress { get; } public BundleDownloadStatus Status { get; } public IEnumerator Download(); }DownloadManager 配置详解DownloadMaxConcurrency最大下载并发数FailedTryAgain失败重试次数Timeout下载超时时间DownloadTask 状态详解Status下载状态Progress下载进度TotalSize总大小DownloadedSize已下载大小BundleDownloader 状态详解Status下载状态Progress下载进度DownloadedBytes已下载字节数三、HTTP 下载实现3.1 UnityWebRequest 封装public class BundleDownloader { private UnityWebRequest _request; private string _remoteURL; private string _localPath; public IEnumerator Download() { // 1. 创建下载请求 _request UnityWebRequest.Get(_remoteURL); _request.timeout 60; // 2. 设置下载处理器 var downloadHandler new DownloadHandlerFile(_localPath); downloadHandler.removeFileOnAbort true; _request.downloadHandler downloadHandler; // 3. 发送请求 yield return _request.SendWebRequest(); // 4. 处理结果 if (_request.result UnityWebRequest.Result.Success) { Status BundleDownloadStatus.Succeed; } else { Status BundleDownloadStatus.Failed; Error _request.error; } } }UnityWebRequest 详解UnityWebRequest 是 Unity 提供的网络请求 API。DownloadHandlerFile 详解DownloadHandlerFile 是文件下载处理器直接将下载的数据写入文件。removeFileOnAbort 详解removeFileOnAbort 设置下载中断时是否删除已下载的文件。3.2 下载进度跟踪public IEnumerator Download() { _request UnityWebRequest.Get(_remoteURL); _request.downloadHandler new DownloadHandlerFile(_localPath); var asyncOp _request.SendWebRequest(); while (!asyncOp.isDone) { // 更新进度 Progress asyncOp.progress; DownloadedBytes (long)(asyncOp.progress * TotalSize); yield return null; } }进度更新详解每帧更新下载进度asyncOp.progress 范围是 0-1。DownloadedBytes 计算详解已下载字节数 进度 × 总大小。3.3 HTTP 超时处理public IEnumerator Download() { _request UnityWebRequest.Get(_remoteURL); _request.timeout 60; // 60 秒超时 _request.downloadHandler new DownloadHandlerFile(_localPath); var startTime Time.realtimeSinceStartup; var asyncOp _request.SendWebRequest(); while (!asyncOp.isDone) { if (Time.realtimeSinceStartup - startTime Timeout) { _request.Abort(); Status BundleDownloadStatus.Timeout; yield break; } yield return null; } }超时检测详解每帧检查是否超时超时则取消请求。四、断点续传实现4.1 断点续传的概念断点续传可以从上次中断的位置继续下载优势减少重复下载节省流量提高下载成功率实现原理使用 HTTP Range 请求告诉服务器从哪个字节开始下载。4.2 HTTP Range 请求实现public IEnumerator Download() { // 1. 检查本地是否已有部分下载的文件 long resumePosition GetResumePosition(); if (resumePosition 0) { // 2. 设置 Range 请求头 _request.SetRequestHeader(Range, $bytes{resumePosition}-); } // 3. 设置下载处理器追加模式 var downloadHandler new DownloadHandlerFile(_localPath, resumePosition 0); _request.downloadHandler downloadHandler; // 4. 发送请求 yield return _request.SendWebRequest(); }Range 请求头详解Range 请求头的格式为bytesstart-end表示从 start 字节开始下载。追加模式详解DownloadHandlerFile 的第二个参数为 appendtrue 表示追加模式。4.3 文件位置记录private long GetResumePosition() { if (File.Exists(_localPath)) { return new FileInfo(_localPath).Length; } return 0; }文件大小获取详解通过 FileInfo 获取已下载的文件大小。断点位置详解断点位置就是已下载的文件大小。4.4 完整性验证public IEnumerator Download() { // ... 下载逻辑 ... // 下载完成后验证文件完整性 if (Status BundleDownloadStatus.Succeed) { if (!VerifyFileIntegrity()) { Status BundleDownloadStatus.Failed; Error File integrity check failed; // 删除损坏的文件 if (File.Exists(_localPath)) File.Delete(_localPath); } } } private bool VerifyFileIntegrity() { string fileHash CalculateFileHash(_localPath); return fileHash BundleInfo.FileHash; }Hash 校验详解计算下载文件的 Hash与 BundleInfo 中的 FileHash 对比。损坏文件处理详解校验失败时删除损坏的文件下次重新下载。五、错误重试5.1 重试策略public IEnumerator Download() { int retryCount 0; int maxRetries 3; while (retryCount maxRetries) { bool success false; yield return DoDownload(result success result); if (success) yield break; retryCount; // 等待一段时间后重试 float waitTime Mathf.Pow(2, retryCount); yield return new WaitForSeconds(waitTime); } Status BundleDownloadStatus.Failed; Error Max retries exceeded; }重试次数详解默认重试 3 次可通过配置调整。指数退避详解重试前等待时间 2^retryCount避免立即重试。5.2 错误分类private bool ShouldRetry(UnityWebRequest request) { switch (request.result) { case UnityWebRequest.Result.ConnectionError: // 网络错误重试 return true; case UnityWebRequest.Result.ProtocolError: // 协议错误根据状态码决定 if (request.responseCode 500) return true; // 服务器错误 return false; // 客户端错误不重试 case UnityWebRequest.Result.DataProcessingError: // 数据处理错误重试 return true; default: return false; } }网络错误详解网络连接失败应该重试。服务器错误详解5xx 状态码是服务器错误可以重试。客户端错误详解4xx 状态码是客户端错误不应该重试。5.3 重试实现public IEnumerator Download() { int retryCount 0; int maxRetries 3; while (retryCount maxRetries) { yield return DoSingleDownload(); if (Status BundleDownloadStatus.Succeed) yield break; if (!ShouldRetry(_request)) { yield break; } retryCount; yield return new WaitForSeconds(Mathf.Pow(2, retryCount)); } }重试条件详解只有可重试的错误才重试。重试间隔详解使用指数退避策略避免频繁重试。六、下载进度计算6.1 整体进度计算public class DownloadTask { public float Progress { get { if (TotalSize 0) return 0; return (float)DownloadedSize / TotalSize; } } public long DownloadedSize { get { long total 0; foreach (var downloader in Downloaders) { total downloader.DownloadedBytes; } return total; } } }整体进度详解整体进度 所有 Bundle 已下载字节数 / 总字节数。DownloadedSize 详解DownloadedSize 是所有 BundleDownloader 的已下载字节数之和。6.2 单个下载进度public class BundleDownloader { public float Progress _totalSize 0 ? (float)_downloadedBytes / _totalSize : 0; }单个下载进度详解单个下载进度 已下载字节数 / 该 Bundle 总大小。6.3 下载速度计算public class DownloadSpeedCalculator { private long _lastBytes; private float _lastTime; public float Speed { get; private set; } public void Update(long currentBytes) { var currentTime Time.realtimeSinceStartup; var timeDelta currentTime - _lastTime; if (timeDelta 1.0f) // 每秒更新一次 { Speed (currentBytes - _lastBytes) / timeDelta; _lastBytes currentBytes; _lastTime currentTime; } } }下载速度详解下载速度 (当前字节数 - 上次字节数) / 时间差。更新频率详解每秒更新一次速度避免抖动。七、并发控制7.1 并发控制的重要性并发控制是 DownloadManager 的重要特性避免过多的网络请求控制带宽使用防止服务器过载7.2 并发控制实现public class DownloadManager { private int _maxConcurrency 10; private QueueDownloadTask _waitingTasks new QueueDownloadTask(); private ListDownloadTask _runningTasks new ListDownloadTask(); public void StartDownload(DownloadTask task) { if (_runningTasks.Count _maxConcurrency) { _waitingTasks.Enqueue(task); return; } _runningTasks.Add(task); task.BeginDownload(); } public void OnTaskComplete(DownloadTask task) { _runningTasks.Remove(task); if (_waitingTasks.Count 0) { var nextTask _waitingTasks.Dequeue(); StartDownload(nextTask); } } }最大并发数详解默认最大并发数为 10可通过 DownloadMaxConcurrency 调整。任务队列详解超过并发数的任务进入等待队列。启动等待任务详解有任务完成时启动等待中的任务。7.3 单任务内部并发public class DownloadTask { private int _maxConcurrency 5; private QueueBundleDownloader _waitingDownloaders new QueueBundleDownloader(); public void Update() { // 启动等待中的下载 while (_currentConcurrency _maxConcurrency _waitingDownloaders.Count 0) { var downloader _waitingDownloaders.Dequeue(); StartDownloader(downloader); } } }任务内部并发详解单个 DownloadTask 也可以控制内部并发。Bundle 并发下载详解单个任务内的多个 Bundle 可以并发下载。八、下载操作 API8.1 下载操作public class DownloadManager { public DownloadTask BeginDownload(ResourcePackage package, ListBundleInfo bundleInfos, int failedTryAgain 0, int timeout 60); public void CancelDownload(DownloadTask task); public void PauseDownload(DownloadTask task); public void ResumeDownload(DownloadTask task); }BeginDownload 详解开始下载返回 DownloadTask。CancelDownload 详解取消下载停止所有下载。PauseDownload 详解暂停下载保存下载进度。ResumeDownload 详解恢复下载从断点继续。8.2 进度查询public class DownloadTask { public float Progress { get; } public long DownloadedSize { get; } public long TotalSize { get; } public DownloadStatus Status { get; } public string Error { get; } }Progress 详解Progress 是下载进度范围 0-1。Status 详解Status 是下载状态包括 Running、Paused、Succeed、Failed、Canceled。8.3 事件回调public class DownloadTask { public event ActionDownloadTask OnDownloadStart; public event ActionDownloadTask OnDownloadProgress; public event ActionDownloadTask OnDownloadComplete; public event ActionDownloadTask OnDownloadError; }事件类型详解OnDownloadStart下载开始OnDownloadProgress下载进度更新OnDownloadComplete下载完成OnDownloadError下载错误九、总结本章深入解析了 YooAsset 下载系统DownloadSystem的源码实现包括下载系统架构分层架构、核心组件HTTP 下载实现UnityWebRequest 封装、进度跟踪、超时处理断点续传实现HTTP Range 请求、文件位置记录、完整性验证错误重试重试策略、错误分类、重试实现下载进度计算整体进度、单个进度、下载速度并发控制并发控制的重要性、实现、单任务内部并发下载操作 API下载操作、进度查询、事件回调通过深入理解 DownloadSystem 的实现开发者可以更好地使用 YooAsset 的热更新功能并优化下载性能。下一篇加密解密机制

相关新闻

Prometheus+Grafana 配置Elasticsearch ,Kafka的启动【Windows环境入门】

Prometheus+Grafana 配置Elasticsearch ,Kafka的启动【Windows环境入门】

Elasticsearch 官网下载:elasticsearch-9.4.3-windows-x86_64.zip 解压 3.修改config/elasticsearch.yml # 本地调试开发单机模式 discovery.type: single-node # 集群模式需要设置 #cluster.initial_master_nodes ["node_1"] # 这几个都改成false访…

2026/7/29 1:23:40 阅读更多 →
如何快速构建企业级一站式数据开发平台:DataSphere Studio终极指南

如何快速构建企业级一站式数据开发平台:DataSphere Studio终极指南

如何快速构建企业级一站式数据开发平台:DataSphere Studio终极指南 【免费下载链接】DataSphereStudio DataSphereStudio is a one stop data application development& management portal, covering scenarios including data exchange, desensitization/clean…

2026/7/26 19:41:36 阅读更多 →
GitHub Copilot、LangChain 与 Claude-code:三大AI编程工具深度解析

GitHub Copilot、LangChain 与 Claude-code:三大AI编程工具深度解析

摘要在AI技术席卷软件开发领域的今天,GitHub Copilot、LangChain和Claude-code是开发者们最常提及的三个名字。它们看似都与“AI编程”相关,但定位、工作方式和适用场景却截然不同。本文将深入剖析这三者的核心差异:Copilot是集成在IDE中的智…

2026/7/29 9:07:20 阅读更多 →

最新新闻

Faiss Python接口实战:从核心原理到大规模向量检索应用

Faiss Python接口实战:从核心原理到大规模向量检索应用

1. 项目概述:从向量搜索到应用落地 如果你正在处理海量的文本、图片或者用户行为数据,并且需要从中快速找到最相似的那一个,那么你很可能已经听说过或者正在寻找一个高效的向量搜索引擎。Faiss,这个由Facebook AI Research团队开源…

2026/7/30 10:15:11 阅读更多 →
Noiz Easter Voice:AI语音生成的趣味彩蛋玩法解析

Noiz Easter Voice:AI语音生成的趣味彩蛋玩法解析

1. Noiz Easter Voice:AI语音生成的新玩法 Noiz Easter Voice是近期在ProductHunt上爆红的一款AI语音生成工具,主打"彩蛋"概念,为用户带来趣味十足的语音创作体验。作为一个长期关注AI语音技术的从业者,我第一时间体验了…

2026/7/30 10:15:11 阅读更多 →
基于大数据的共享单车调度优化与热力分析

基于大数据的共享单车调度优化与热力分析

1. 项目概述:当共享单车遇上大数据去年夏天,我在杭州街头连续三天看到同一辆共享单车停在小区门口,车篮里积满了雨水。这个画面让我意识到,共享单车的调度问题远比想象中复杂。这正是我们团队选择"基于大数据的共享单车数据分…

2026/7/30 10:15:11 阅读更多 →
2026年大数据分析软件推荐:性能与安全对比

2026年大数据分析软件推荐:性能与安全对比

大数据分析早已不是大厂的专属需求。随着企业数据量普遍增长,越来越多中型企业也面临同样的挑战:数据量上了亿级、数据源从三五个变成了十几个、分析场景从几张固定报表变成了多部门并发自助查询。此时选一款能扛得住数据量和并发压力、同时满足安全合规…

2026/7/30 10:15:11 阅读更多 →
vscode 可视化 git history commit 对比两个特定 commit

vscode 可视化 git history commit 对比两个特定 commit

vscode 的可视化 git history commit 只能看单个 commit 的修改。 我想看到从 commit1 -> commit 100 的整合修改,但又不想用 git rebase 去 squash 这些 commits,有办法吗? 回答,首先在可视化 git history 那里,选…

2026/7/30 10:15:11 阅读更多 →
顺序查找与折半查找:时间复杂度对比与408考研重点解析

顺序查找与折半查找:时间复杂度对比与408考研重点解析

这次我们来看顺序查找和折半查找这两个数据结构中的基础算法。对于准备408计算机考研的同学来说,这两个算法不仅是必考内容,更是理解更复杂搜索算法的基础。本文将通过一图流的方式直观展示算法流程,并提供完整的代码实现和考研重点分析。 顺…

2026/7/30 10:14:11 阅读更多 →

日新闻

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:13 阅读更多 →
如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经在浏览…

2026/7/30 0:00:13 阅读更多 →
“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

更多请点击: https://intelliparadigm.com 第一章:AI 教师备课辅助 AI 教师备课辅助系统正逐步成为教育数字化转型的核心支撑工具,它并非替代教师,而是通过语义理解、知识图谱与多模态生成能力,将教师从重复性劳动中解…

2026/7/30 0:00:13 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/29 22:18:20 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻