There are two different APIs that you can use to load AssetBundles.
This API is highly-efficient when loading uncompressed and chunk compressed bundles (LZ4) from local storage because it can read content of the file incrementally, directly from disk. Loading a file that is compressed with full file compression (LZMA) using this method is less efficient because it requires that the file be fully decompressed into memory first.
以下は LoadFromFile
の使用方法の一例です。
using System.IO;
using UnityEngine;
public class LoadFromFileExample : MonoBehaviour
{
void Start()
{
var myLoadedAssetBundle = AssetBundle.LoadFromFile(Path.Combine(Application.streamingAssetsPath, "myassetBundle"));
if (myLoadedAssetBundle == null)
{
Debug.Log("Failed to load AssetBundle!");
return;
}
var prefab = myLoadedAssetBundle.LoadAsset<GameObject>("MyObject");
Instantiate(prefab);
}
}
Rather than blocking your app during the load process you can also use the asynchronous version, AssetBundle.LoadFromFileAsync
.
There are several other methods available to load an AssetBundle if it is not actually stored in a local file. For example you can use AssetBundle.LoadFromMemoryAsync.
The UnityWebRequestAssetBundle API can be called to create a special web request for downloading, caching and loading AssetBundles.
Typically the URL would be a ‘https://’ address pointing to the file as exposed by a web service. It could also be ‘file://’ to access local data on platforms that do not support direct file system access.
This request can be passed into DownloadHandlerAssetBundle.GetContent(UnityWebRequestAssetBundle) to get the AssetBundle object for the loaded AssetBundle.
For example
using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
public class DownloadExample : MonoBehaviour
{
IEnumerator Start()
{
string uri = "https://myserver/myBundles/bundle123";
uint crc = 1098980; // Expected content CRC
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri, crc);
yield return request.SendWebRequest();
AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);
var loadAsset = bundle.LoadAssetAsync<GameObject>("Assets/Players/MainPlayer.prefab");
yield return loadAsset;
Instantiate(loadAsset.asset);
}
}
For simplicity the example shows a CRC value that is hardcoded in the code. But in practice the expected CRC values for your AssetBundles would be downloaded separately, or retrieved from a file, prior to downloading the AssetBundles. See AssetBundle Download Integrity and Security.
Note: In order to avoid downloading the entire AssetBundle content each time this code is called you could enable caching for your AssetBundle. This is done by passing the AssetBundle hash when calling UnityWebRequestAssetBundle.GetAssetBundle. The hash is available from the AssetBundle Manifest, which is described later in this section. The hash acts as version identifier for the precise build of the AssetBundle that you are requesting. See AssetBundle compression and caching for details of the Cache and the associated considerations about compression.
Now that you’ve successfully loaded your AssetBundle, it’s time to finally load in some Assets.
汎用コード スニペット
T objectFromBundle = bundleObject.LoadAsset<T>(assetName);
T は、ロードするアセットのタイプです。
アセットのロード方法はいくつかあります。 LoadAsset
と LoadAllAssets
および、それらの Async バージョンである LoadAssetAsyncと
LoadAllAssetsAsync` です。
アセットバンドルから同期的にアセットをロードする方法は以下の通りです。
To load a single Asset (for example the root GameObject of a Prefab):
GameObject gameObject = loadedAssetBundle.LoadAsset<GameObject>(assetName);
全てのアセットをロードするには以下を使用します。
Unity.Object[] objectArray = loadedAssetBundle.LoadAllAssets();
This returns an array with all the root Object of each Asset.
Now, whereas the previously shown methods return either the type of object you’re loading or an array of objects, the asynchronous methods return an AssetBundleRequest. You’ll need to wait for this operation to complete before accessing the asset. To load an asset asynchronously:
AssetBundleRequest request = loadedAssetBundleObject.LoadAssetAsync<GameObject>(assetName);
yield return request;
var loadedAsset = request.asset;
または
AssetBundleRequest request = loadedAssetBundle.LoadAllAssetsAsync();
yield return request;
var loadedAssets = request.allAssets;
アセットのロードが終わったら、準備完了です。ロードされたオブジェクトを、その他のオブジェクトと同じように Unity 上で使用することができます。
アセットバンドル マニフェストをロードすると非常に役立ち得ます。特にアセットバンドルの依存関係を扱う場合には有益です。
使用可能な AssetBundleManifest オブジェクトを取得するには、追加のアセットバンドル (その格納されているフォルダーと同じ名前のアセットバンドル) をロードし、 AssetBundleManifest タイプのオブジェクトを 1 つ、そこからロードする必要があります。
マニフェスト自体のロードは、その他通常のアセットをアセットバンドルからロードする場合と全く同じように行われます。
AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath);
AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
これで、上記の例にあるマニフェストオブジェクトによって AssetBundleManifest
API コールが使用できるようになりました。ここからは、ビルドしたアセットバンドルの情報を、マニフェストを使用して取得することができます。この情報には、該当のアセットバンドルの依存関係データ、ハッシュデータ、バリアントデータが含まれます。
The earlier section on AssetBundle Dependencies discussed how, in order to load an Asset from an AssetBundle, you must first load any AssetBundles that the AssetBundle depends on. The manifest object makes dynamically finding and loading dependencies possible, so you do not have to hardcode all the AssetBundle names and their relationships explicitly in your code. Let’s say we want to load all the dependencies for an AssetBundle named “assetBundle”.
AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath);
AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
string[] dependencies = manifest.GetAllDependencies("assetBundle"); //依存関係を取得するバンドル名を渡します
foreach(string dependency in dependencies)
{
AssetBundle.LoadFromFile(Path.Combine(assetBundlePath, dependency));
}
これでアセットバンドル、アセットバンドルの依存関係、アセットのロードが完了しました。次は、ロードしたアセットバンドルの管理についての解説です。
Note: The Addressables package provides a ready-made system to manage loading AssetBundles, dependencies, and Assets. Unity recommends using Addressables rather than managing AssetBundles yourself.
Unity Learn の ロードされたアセットバンドルの管理に関するチュートリアル も参照してください。
Unity は、アクティブなシーンから削除されたオブジェクトを自動的にアンロードしません。アセットのクリーンアップは特定の時点でトリガーされますが、手動でトリガーすることも可能です。
It is important to know when to load and unload an AssetBundle. Improperly unloading an AssetBundle can lead to duplicating objects in memory or missing objects.
The biggest things to understand about AssetBundle management is when to call AssetBundle.Unload(bool) – or AssetBundle.UnloadAsync(bool) – and if you should pass true or false into the function call. Unload is a non-static function that will unload your AssetBundle by removing the AssetBundle header and other data structures from memory. The argument indicates whether to also unload all Objects instantiated from this AssetBundle.
AssetBundle.Unload(true)
unloads all GameObjects (and their dependencies) that were loaded from the AssetBundle. This does not include objects that you have copied into your scene (e.g. by calling Instantiate
) because that copied data does not belong to the AssetBundle. If the objects in your scene references Textures that were loaded from the AssetBundle (and still belong to it), then this call will cause the Textures to disappear, and Unity treats them as missing Textures.
As an example, let’s assume Material M is loaded from AssetBundle AB as shown below and used in Prefab P.
If AB.Unload(true) is called then any instance of M referenced from objects in the active scene will be destroyed.
If you were instead to call AB.Unload(false) then the instances of M will remain in memory. They will become independent objects that are not linked back to the original AssetBundle.
If AB is loaded again later Unity will not re-link the existing copies of M to the Material inside the AssetBundle.
If you create another instance of Prefab P, it will not use the existing copy of M. Instead a second copy of M is loaded.
Generally, using AssetBundle.Unload(false)
can lead to duplicated objects and other issues. Most projects should use AssetBundle.Unload(true)
to avoid this. There are two common strategies for safely calling AssetBundle.Unload(true)
:
アプリケーションのライフタイム内で、一時的なアセットバンドルをアンロードする丁度良いタイミングを設定する。例えばステージとステージの間やロード画面など。
個々のオブジェクトの参照カウントを維持し、アセットバンドルに含まれるオブジェクトがひとつも使用中でない場合にのみ、アセットバンドルをアンロードする。この方法だと、メモリの重複を起こすことなく、アプリケーションのオブジェクトを個々にアンロードおよびリロードできます。
どうしても AssetBundle.Unload(false)
の使用が必要なアプリケーションの場合、個々のオブジェクトをアンロードする方法は次の 2 つのみになります。
Eliminate all references to an unwanted Object, e.g. make sure no other loaded object has a field that points to it. After this is done, call Resources.UnloadUnusedAssets.
非加算的にシーンをロードする。これにより、現在のシーン内の全てのオブジェクトが破棄されて Resources.UnloadUnusedAssets が自動的に実行されます。
Did you find this page useful? Please give it a rating:
Thanks for rating this page!
What kind of problem would you like to report?
Thanks for letting us know! This page has been marked for review based on your feedback.
If you have time, you can provide more information to help us fix the problem faster.
Provide more information
You've told us this page needs code samples. If you'd like to help us further, you could provide a code sample, or tell us about what kind of code sample you'd like to see:
You've told us there are code samples on this page which don't work. If you know how to fix it, or have something better we could use instead, please let us know:
You've told us there is information missing from this page. Please tell us more about what's missing:
You've told us there is incorrect information on this page. If you know what we should change to make it correct, please tell us:
You've told us this page has unclear or confusing information. Please tell us more about what you found unclear or confusing, or let us know how we could make it clearer:
You've told us there is a spelling or grammar error on this page. Please tell us what's wrong:
You've told us this page has a problem. Please tell us more about what's wrong:
Thank you for helping to make the Unity documentation better!
Your feedback has been submitted as a ticket for our documentation team to review.
We are not able to reply to every ticket submitted.