これはメインバンドルのサイズが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製ゲームでは、 Breakneck や Bruce Lee: Enter the Game – Unchained Edition など、すでにオンデマンドリソースを活用したものがApple TVでリリースされています。