4

私たちは、ゲームが「すぐに」必要とするさまざまなリソースを「バックグラウンドで同時に」ダウンロードする方法を探しています。私たちの要件は、(1)可能な限り最大のダウンロード速度、(2)ゲームを推進している「フォアグラウンド」Runloopアクティビティの可能な限り最小の中断、(3)ソリューションは私たちが関心を持つすべての主要なプラットフォーム(Android / iOS)で非常にうまく機能することです。 / PC / Mac)、および(4)ソリューションを弱体化させるバグがないこと。

要件1を満たしていない場合は、ゲームを停止し、バックグラウンドダウンロードが追いついて、必要なリソースを提供するまでユーザーを待たせる必要があります。要件2を満たしていない場合、バックグラウンドダウンロードはゲームのプレイ方法に悪影響を及ぼし、ゲームがぎくしゃくしたり、応答が遅くなったりします。

アセットバンドル、WWW、ネイティブC#HttpWebRequestなど、さまざまなアプローチを試し、調査しましたが、いずれも要件をすべて満たしていません。詳細は以下をご覧ください。

この問題を解決する方法をすでに理解している場合は、車輪の再発明をしたくないので、チャットしたいと思います。

これまでの経験の詳細は次のとおりです。

UnityにAndroidアプリが組み込まれていますが、最終的にはiOS経由でも利用できるようになります。通常のフォアグラウンドアクティビティに加えて、フォアグラウンドでアプリが使用するさまざまなリソースをダウンロードするというバックグラウンドの優先度の低いアクティビティがあります。

(質問する前に、アセットバンドルは、最近何かが変更されていない限り、Unityのさまざまなバージョン間で機能しないため機能しません。つまり、Unity3.4のアセットバンドルはUnity3.5では機能しません。したがって、アップグレードするユーザーは次のようになります。すべてのアセットをもう一度ダウンロードし直します。)

残念ながら、「WWW」コンポーネントの使用には多くの厄介なバグが見つかりました。これには、ネットワークが失われたときに更新されないことや、Web要求(つまり「post」)からの戻り値がないことが含まれます。そのため、WWWの使用をネイティブのC#HttpWebRequestに置き換えることを検討しています。残念ながら、コルーチンを介してメインのUnity Runloopでこのコンポーネントを使用すると、runloopがストールし、UIがフリーズすることがわかりました。

ただし、これと同じコードをバックグラウンドのC#スレッド(コルーチンではない)に配置してから、そのスレッドのアクティビティをポーリングすることは機能しているようです。

Unityスケジューラーと調和したこのアクティビティを離れた場所でスケジュールできるため、このアプローチは好きではありません。ネットワーク(および関連するCPU)アクティビティを、UnityRunLoopの適切なギャップで実行する必要があります。しかし、私たちが知る限り、優先順位を指定する方法は3つしかありません。

  • WWW.threadPriority-WWWを使用したくないので、これはミュートです。
  • Application.backgroundLoadingPriority-ダウンロードを行うためにUnityコンポーネント(AssetBundlesなど)を使用していないため、これは効果がないと思いますか?
  • YieldInstructions(例:WaitForSecondsやWaitForFixedUpdate)-私の理解では、これらはかなり馬鹿げています。それらは実行がスケジュールされているときに実行され、Unity Run Loopのニーズに従わないのですか?

私たちが理解しようとしていること:-WWWは本当に問題を抱えているのでしょうか、それともこれは単にコンポーネントを使用しているだけなのですか?--UnityアプリでHttpWebRequestを正常に使用した人はいますか?彼らはスレッド化された方法でそうしましたか?-バックグラウンドタスクがUnityRunloopでうまく再生され、グリッチや競合を引き起こさないように、Unityに「割り込み」または「優先」アーキテクチャがありますか?

4

1 に答える 1

0

簡単なグーグル検索で、WWW を使用したくない場合にこの魔女が機能する可能性があることがわかりました。以前に使用したことのある system.net には webclient もありますが、ユニティ内ではありませんが、非同期ダウンロードがあることはわかっているので、ここで使用しました

ウェブクライアントの例:

WebClient webClient = new WebClient();

webClient.DownloadProgressChanged += OnChange;
webClient.DownloadFileCompleted += OnCompleted;
webClient.DownloadFileAsync(new Uri(download), fileAndPath);
于 2014-02-28T05:43:24.547 に答える