Search Unity

オンデマンドリソースはtvOSバージョン9から導入された新しいiOSの機能です。この機能の目的はメインアプリケーションバンドルのサイズを削減することで、開発者が一部のリソースをメインアプリケーションバンドルから切り分け、それをApp Storeのインフラでホストしてオンデマンドにダウンロード出来るようにします。

これはメインバンドルのサイズが200MB以下に制限されているAppleTVプラットフォームではとても重要な機能です。ほとんどのデベロッパーはダイナミックにロードされたリソースを何らかの形で使う必要が出るでしょう。デベロッパーの人生を楽にするために、UnityはオンデマンドリソースのためのAPIラッパーをUnity 5.2.0p1 から提供しています。

オンデマンドリソースはアプリケーションの最初のダウンロードサイズを小さくするためにも、もう使わないリソースを削除してデバイスのストレージを節約するためにも使えます。一般的には、アプリケーションの起動自体に必要ないリソースであれば、オンデマンドでロード・アンロードが出来るリソースの対象となりえます。例えばステージ単位のゲームを考えてみましょう。プレイヤーがステージ3をまだプレイしているのであれば、アプリケーションはステージ10のリソースは必要としません。その一方で、プレイヤーがステージ16を遊んでいるのであれば、最初のステージは安全にアンロード出来るかもしれません。

オンデマンドリソースの利点を活かす最も簡単なやり方はアセットバンドルを活用することです。アセットバンドルはダイナミックアセットローディングの多くの問題、たとえばメモリやCPU効率、それに依存関係の解決やターゲットプラットフォームへの最適化といったものを解決してくれます。アセットバンドルが設定されたら、あとは下記の例にあるようなほんのちょっとの変更を加えるだけでオンデマンドリソースを使うことができます。このブログ記事ではアセットバンドルについてはカバーしませんが、もしこの記事でアセットバンドルについて初めて目にするという場合は、このリソースが役に立つでしょう。

オンデマンドリソースを使うためには、開発者は2つのアクションを行う必要があります。ビルド時に タグ(tag) と呼ばれるIDを各リソースに設定して、アプリケーションの実行時にリソースが必要になった時にこのタグを通して取得します。普通のiOSアプリケーション開発では、タグを割り当てはXcodeから行い、リソースの取得はNSBundleResourceRequest APIを通して行います。Unity上では、タグの割り当てとリソースの回収はどちらもスクリプトを通して行います。タグの割当ては UnityEditor.iOS.BuildPipeline.collectResources イベント API を通じて、そしてリソースの取得は UnityEngine.iOS.OnDemandResources.PreloadAsync APIを通して行います。

現在のオンデマンドリソースAPIはタグ名に対してどのような制約もないため、開発をシンプルにするポイントいくつかあります。まずタグの付け方ですが、各アセットバンドルに対してアセットバンドル名自体を個別のタグとしてつけることをオススメします。これがもっともフレキシブルかつ簡単なアプローチで、この方法なら開発者はそれぞれのダウンロードに対してプライオリティを設定できるし、それぞれのダウンロード状況を取得することも出来ます。さらに、Appleはダウンロード速度とストレージ消費量のバランスのために、一つのタグに割り当てられるリソースの合計が64MBを超えないことを推奨している、ということも覚えておきましょう。

以下の2つのコード例はオンデマンドリソースを使う時に必要な処理のデモです:

タグをリソースに割り当てるエディタースクリプト:
[csharp]
using UnityEditor.iOS;
#if ENABLE_IOS_ON_DEMAND_RESOURCES
public class BuildResources
{
[InitializeOnLoadMethod]
static void SetupResourcesBuild()
{
UnityEditor.iOS.BuildPipeline.collectResources += CollectResources;
}
static UnityEditor.iOS.Resource[] CollectResources()
{
return new Resource[] {
new Resource("asset-bundle-name", "path/to/asset-bundle").AddOnDemandResourceTags("asset-bundle-name-tag"),
};
}
}
[/csharp]
実行時にリソースを取得するスクリプト:
[csharp]using UnityEngine.iOS;

// We can execute the following function as a coroutine, like this:
// StartCoroutine(LoadAsset("asset-bundle-name", "asset-bundle-name-tag"));
public static IEnumerator LoadAsset(string resourceName, string odrTag)
{
// Create the request
var request = OnDemandResources.PreloadAsync(new string[] { odrTag } );
// Wait until request is completed
yield return request;
// Check for errors
if (request.error != null)
throw new Exception("ODR request failed: " + request.error);
// Now we can use the resource, for example, by loading an asset bundle like this:
// var bundle = AssetBundle.CreateFromFile("res://" + resourceName);
// …
// We need to call Dispose() when resource is no longer needed.
// request.Dispose();
}[/csharp]
アセットバンドルとオンデマンドリソースについての検討を始めるのに一番簡単な方法は、BitBucketで提供されているAsset Bundle Manager デモプロジェクトを使うことです。ランディングページにはこのデモの使い方と変更の仕方についての詳しい説明があります。

いくつかのUnity製ゲームでは、 BreakneckBruce Lee: Enter the Game – Unchained Edition など、すでにオンデマンドリソースを活用したものがApple TVでリリースされています。

コメント受付を終了しました。

  1. imaginaryhuman

    11月 27, 2015 7:55 pm

    any news on when the appltv build target will be available in unity?

  2. i wanna know if support ios8~or ios7…because this is difference from old version assets manager.

    1. No. You can only use it if iOS Deployement Target is set to iOS 9.0.

      Of course in theory you can use OnDemandResources for iOS >= 9.0 and AssetBundles downloaded from www for iOS < 9.0, but you can't publish that app: Apple rejects app if you use OnDemandResources code and iOS Deployement Target is less than 9.0 (tried that).

      1. When you say ‘deployment target’ you mean ‘Target minimum iOS Version’ in Unity player settings?

        1. Yes. Target minimum iOS Version must be set to 9.0.

  3. imaginaryhuman

    11月 26, 2015 6:27 pm

    Sounds cool. The asset bundles seem easy enough to use. But I am put off by the on-demand resource that need us to dip into complicated-looking script in order to use them. Why isn’t there a very simple built-in widget or option in the Unity editor to take all the pain out of this, to just tag resources or whatever and have all of the on-demand management stuff just ‘happen’ automagically?

    1. Scripting based interface gives you best flexibility for integration with your build systems. That’s why we started with it. We are researching how to expose this functionality through GUI in a convenient manner for next updates of this feature.

      1. Yes! Please help us take the pain out of this process with some GUI plug-and-play automagic! Apple TV looks like an exciting platform but all that asset management gives me hives. Help, Unity!