【译】精通苹果平台的按需加载资源(On-Demand Resources)
精通苹果平台的按需加载资源
作者:Povilas Kanapickas
按需加载资源是IOS和tvOS 9.0版本引入的一项新技术。它的目的是减少主要应用包的大小,这样开发者可以把特定的资源从主要应用包中分离出来,放在应用商店的机器上按需下载。
这个技术对于新的AppleTV平台是非常重要的,因为它限制主要应用包的大小在200MB以内。因此,大部分开发者需要这样或者那样的动态加载资源方式。为了减少开发者的负担,Unity从Unity 5.2.0 patch 1版本开始封装了按需加载资源的API。
通过按需加载资源的技术来移除不再需要的资源,你既可以减初始应用程序下载包的大小,还能减少设备存储空间的使用量。总的来说,任何不是启动一个用所必需的资源都可以被用来按需加载或者卸载。比如,对于一个关卡游戏:在用户还在玩第3关的时候,应用并不需要第10关的资源。另外一方面,当用户在玩第16关的时候,第一关的资源可以安全的释放掉。
使用按需加载资源最方便的方法就是通过assert bundles. Assetbundles解决了动态加载资源的很多问题,比如内存和CPU效率、依赖关系的记录以及对于特定平台的优化。一旦assert bundles被配置好,你只需要很少的额外改动来按需加载资源,如下面的代码例子所示。在这篇文章里我们不会涉及assert bundles的内容。如果这是你头一次听说assert bundles,这个网址(http://unity3d.com/cn/learn/tutorials/topics/scripting/assetbundles-and-assetbundle-manager)将帮助你了解它们。
为了使用按需加载资源,开发者需要做两个事情:在构建过程中给每个资源分配一些被称为标签的标识符,在应用运行的时候每个资源都使用所分配的标签。在vanilla这个IOS应用的开发过程中,第一步是在Xcode中给每个资源分配一个标签,而字眼使用NSBundleResourceRequestAPI。在Unity中,标签分配和资源检索都是通过代码来完成的:前者使用UnityEditor.iOS.BuildPipeline.collectResources,后者使用UnityEngine.iOS.OnDemandResources.PreloadAsync。
虽然现在的按需加载资源API并不限制标签的名字,但还是有几种指导原则来简化开发。最好为每个asset bundle分配一个源于asset bundle包的名字。这样提供了最大的灵活性,也最简单。在这种情况下,开发者能够给每个单独的下载包设置优先级并且检索每一个包的下载进度。另外,苹果公司推荐所有使用同一个标签的资源累积大小不超过64MB,这是为了寻求下载速度和存储空间可用性之间的平衡。
下面的两个代码示例展示了使用按需加载资源的关键:
给资源分配标识符的编辑器脚本:
usingUnityEditor.iOS;
#ifENABLE_IOS_ON_DEMAND_RESOURCES
publicclass 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"),
};
}
}
运行时检索资源:
usingUnityEngine.iOS;
//We can execute the following function as a coroutine, like this:
//StartCoroutine(LoadAsset("asset-bundle-name","asset-bundle-name-tag"));
publicstatic 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 requestfailed: " + 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 isno longer needed.
// request.Dispose();
}
开始使用asset bundles和按需加载资源最简单的方法是使用我们的Asset Bundle Manager 工程,可以在Bitbucket上下载到(https://bitbucket.org/Unity-Technologies/assetbundledemo)。登陆页面有一个如何使用和调整demo比较容易理解的描述。
Apple Tv上已经有几个游戏使用了按需加载资源。包括了Breakneck和Bruce Lee: Enter the Game – Unchained Edition。