我们正在寻找一种方法来“在后台同时”下载我们的游戏“很快”需要的各种资源。我们的要求是 (1) 最大可能的下载速度,(2) 对推动游戏的“前台”Runloop 活动的最小可能中断,(3) 该解决方案在我们感兴趣的所有主要平台(Android/iOS)上都运行得非常好/PC/Mac),和 (4) 不存在削弱解决方案的错误。
如果我们不满足要求#1,那么游戏必须停止并让用户等待后台下载赶上并提供必要的资源。如果我们不满足要求 2,那么后台下载会对游戏的运行方式产生负面影响,使其变得生涩或响应缓慢等。
我们已经尝试并调查了各种方法,包括 Asset Bundles、WWW 和原生 C# HttpWebRequest,但它们都不能满足我们的所有要求。详情如下。
如果您已经弄清楚如何解决这个问题,我们很乐意与您交谈,因为我们宁愿不重新发明轮子。
以下是我们迄今为止的经验的详细信息:
我们有一个内置在 Unity 中的 Android 应用程序 - 最终也可以通过 iOS 使用。除了正常的前台活动外,我们还有一个后台低优先级活动,即下载各种资源以供前台应用程序使用。
(在你问之前,Asset Bundles 对我们不起作用——除非最近发生了任何变化——它们不能跨不同版本的 Unity 工作——即 Unity 3.4 的资产包在 Unity 3.5 中不起作用。所以升级用户将拥有重新下载他们所有的资产。)
不幸的是,我们在使用“WWW”组件时发现了一些恼人的错误。这些包括在网络丢失时不更新,以及网络请求(即“发布”)没有返回值。因此,我们希望用本机 C# HttpWebRequest 替换我们对 WWW 的使用。不幸的是,我们发现通过协程在主 Unity Runloop 中使用这个组件会导致 runloop 停止并且 UI 冻结。
但是将相同的代码放在后台 C# 线程(不是协同程序)中,然后轮询该线程的活动似乎确实有效。
我们不喜欢这种方法,因为它确实允许我们将这个活动安排在与 Unity 调度程序一致的范围内。我们希望网络(和相关的 CPU)活动在 Unity Run Loop 的适当间隙中运行。但据我们所知,只有三种方式可以指定优先级:
- WWW.threadPriority - 我们不想使用 WWW,所以这是静音的。
- Application.backgroundLoadingPriority - 由于我们没有使用 Unity 组件(如 AssetBundles)进行下载,我假设这没有效果?
- YieldInstructions 例如 WaitForSeconds 和 WaitForFixedUpdate - 我的理解是这些都相当愚蠢。它们在计划运行时运行并且不遵循 Unity Run Loop 的需求?
我们希望了解的内容: - WWW 是否真的充满了问题,或者这只是我们对组件的使用?- 有没有人成功使用过带有 Unity 应用程序的 HttpWebRequest?他们是否以线程化的方式这样做?- Unity 中是否有任何“中断”或“优先”架构,以便后台任务可以很好地与 Unity Runloop 一起运行,而不会导致故障或竞争?