【发布时间】:2012-08-24 18:15:48
【问题描述】:
我们正在寻找一种“在后台同时”下载我们的游戏“很快”需要的各种资源的方法。我们的要求是 (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 中很好地运行,而不会导致故障或竞争?
【问题讨论】:
-
您有没有找到好的解决方案?如果有,可以分享一下吗?
-
Unity Player 作为单线程运行(只有一个主循环),如果您需要后台下载线程,可以使用Unity plugin approach。例如,在 Android 上,您可以创建一个下载活动来与主要的 Unity Player 活动配合。
标签: android ios networking background unity3d