首页 > Unity3D频道 > 【Unity3D研究院之游戏开发】 > Unity边玩边下限制下载速度
2022
09-09

Unity边玩边下限制下载速度

Unity提供了DownloadHandlerFile类来进行文件的下载,如果是那种网络比较好的宽带每秒下载速度可以达到20M以上,这样导致IO容易卡住。如果是进游戏前那种提前下载肯定没问题,但是边玩边下这种如果不限制下载速度那么游戏就不会那么流畅了。

Unity提供了DownloadHandlerScript类,开始我以为只要用FileStream自己来写一个比较小长度的Buffer就可以解决问题。如下代码所示,实际测试了一下ReveiveData会在一帧内回调多次导致write操作卡住IO,所以此思路只能作罢。

既然Unity的API实现不了只能使用C#的API了。我们先达成一个共识,边玩边下同一时刻只能下载一个文件(游戏不卡顿优先,其次才是下载),所以缓冲Buffer可以分配一个静态的。假设最大的下载速度是1M/S 每秒30帧那么每帧Buffer的长度1024/30*1024。

每帧处理的Buffer字节数组已经确定,接着就是要开线程下载了。使用await Task.Run来开线程,它的好处是可以等子线程的下载任务结束在回到主线程,这样就可以把下载完成的事件抛出让逻辑层处理。下载过程中还需要考虑强制断开的问题,可以使用CancellationToken即可。

下载连接建立好以后就开始下载,启动一个while循环,为了避免IO的卡住,这里需要让线程sleep下来。最后就是上完整的代码了。

启动下载调用的代码,这里可以监听下载完成的事件以及错误信息。

下载过程中取消下载

注意如果是下载file://开头的本地文件, 需要在代码中将HttpWebRequest和HttpWebResponse换成FileWebRequest和FileWebResponse其他地方都完全一样。

最后在总结一下资源下载。目前根据我们的经验会将下载分成两部分,一部分是启动下载,另一部分是边玩边下。

先说启动下载,它需要尽可能的快,一般这种下载展示就是一个普通的下载进度条,它并不要求高帧率,需要尽最快速度下载完毕。针对这种下载类型可以直接使用unity的DownloadHandlerFile,但是在面对小文件(几K几十K大小)的时候下载速度是非常慢的,因为针对每个文件需要单独建立http的链接,这些都需要额外开销。反而如果是大文件(百M以上大小),每秒下载好几十M都是可以的。

在针对下载小文件慢的问题上其实是可以增加同时下载的数量的,比如同时下载的资源大小不超过一个阀值就继续开下载队列,目前我项目最大开了30个下载队列,动态根据当前下载文件的小灵活变更数量,尽可能保证下载速度足够快。

其次就是边玩边下了,它和启动下载有个本质区别,边玩边下是不能影响用户游戏体验的,如果用户觉得游戏卡住很可能一开始就流失了。也就是说宁可下载的慢也不能下载太快影响操作体验,所以就有了这篇文章的限速。

另外Unity提供的几个下载的类都在这类,核心都是在C++中完成的。

Unity边玩边下限制下载速度 - 雨松MOMO程序研究院 - 1

这篇文章起到一个抛砖引玉的过程,欢迎大家一起来讨论,代码是可以直接运行,欢迎大家测试。

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

留下一个回复

你的email不会被公开。