Build and load Assetbundles in Unity

22,158

In this example below, I will demonstrate how to add new asset called "dog" to our AssetBundle named "animals" and build it then load it during run-time.

Setting Up Build Folders:

1. Select the asset such as image file. In this case, that's the "dog.jpeg" file. See the menu in the "Inspector" tab. Sometimes, the AssetBundle option it is hidden, drag it up to show it. See the animated gif below for how to do this. The default AssetBundle is "None". Click on the "None" option then go to the "New" option and create new AssetBundle and name it "animals"

enter image description here

2. Create a folder named StreamingAssets in the Assets folder. This is the folder we are going to build the AssetBundle into. Spelling counts and it's case sensitive so make sure to name it correctly.

enter image description here

3. Create sub-folder in the StreamingAssets folder to hold the AssetBundle. For this example, name this folder AssetBundles so that you can use it to recognize what's in it.

enter image description here


Building AssetBundle:

4. Below is the build script.

A. Create a script named ExportAssetBundles and put it in a folder named "Editor" in the Assets folder then copy the code below inside it:

using System.IO;
using UnityEditor;
using UnityEngine;

public class ExportAssetBundles
{
    [MenuItem("Assets/Build AssetBundle")]
    static void ExportResource()
    {
        string folderName = "AssetBundles";
        string filePath = Path.Combine(Application.streamingAssetsPath, folderName);

        //Build for Windows platform
        BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);

        //Uncomment to build for other platforms
        //BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.iOS);
        //BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.Android);
        //BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.WebGL);
        //BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneOSX);

        //Refresh the Project folder
        AssetDatabase.Refresh();
    }
}

enter image description here

B. Build your AssetBudle by going to Assets --> Build AssetBundle menu.

You should see the built AssetBundles inside the Assets/StreamingAssets/AssetBundles directory. If not, refresh the Project tab.

enter image description here


Loading the AssetBundle during run-time:

5. When loading it, Application.streamingAssetsPath should be used to access the StreamingAssets folder. To access all the folders use, Application.streamingAssetsPath + "/AssetBundle/" + assetbunlenameWithoutExtension;. The AssetBundle and AssetBundleRequest API are used to load the AssetBundle. Since this is an image, Texture2D is passed to them. If using a prefab, pass GameObject instead then instantiate it. See comment in code for where these changes should be made. It is recommended to use Path.Combine to combine path names so the code below should use that instead.

Below is a simple loading function:

IEnumerator LoadAsset(string assetBundleName, string objectNameToLoad)
{
    string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "AssetBundles");
    filePath = System.IO.Path.Combine(filePath, assetBundleName);

    //Load "animals" AssetBundle
    var assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(filePath);
    yield return assetBundleCreateRequest;

    AssetBundle asseBundle = assetBundleCreateRequest.assetBundle;

    //Load the "dog" Asset (Use Texture2D since it's a Texture. Use GameObject if prefab)
    AssetBundleRequest asset = asseBundle.LoadAssetAsync<Texture2D>(objectNameToLoad);
    yield return asset;

    //Retrieve the object (Use Texture2D since it's a Texture. Use GameObject if prefab)
    Texture2D loadedAsset = asset.asset as Texture2D;

    //Do something with the loaded loadedAsset  object (Load to RawImage for example) 
    image.texture = loadedAsset;
}

Things to before loading note:

A. Name of Assetbundle is animals.

B. Name of the asset/object we want to load from the animals Assetbundle is dog This is a simple jpg of a dog.

enter image description here

C. The loading is simple as this:

string nameOfAssetBundle = "animals";
string nameOfObjectToLoad = "dog";

public RawImage image; 

void Start()
{
    StartCoroutine(LoadAsset(nameOfAssetBundle, nameOfObjectToLoad));
}
Share:
22,158
Gideons
Author by

Gideons

Updated on July 27, 2022

Comments

  • Gideons
    Gideons almost 2 years

    I cannot get Unity Assetbundles working in an iOS build.

    In Unity I build the assetbundles:

    using UnityEditor;
    
    public class CreateAssetBundles
    {
        [MenuItem("Assets/Build AssetBundles")]
        static void BuildAllAssetBundles()
        {
            BuildPipeline.BuildAssetBundles("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.iOS);
        }
     }
    

    And they work fine in Unity. using them with

    AssetBundle bundleLoadRequest = AssetBundle.LoadFromFile("file://" + Application.dataPath + "/AssetBundles/iOS/" + myassetbundlename.ToString());
    

    and/or

    WWW wwww = WWW.LoadFromCacheOrDownload("file://" + Application.dataPath + "/AssetBundles/iOS/" + myassetbundlename.ToString(), 4); 
    

    (Without the "file://" prefix, the bundles won't work in Unity nor Xcode)

    I build the project to Xcode and run it in Xcode and receive this error:

    Unable to open archive file: /Users/user/Documents/Workspaces/unityproject/Assets/AssetBundles/iOS/lchairanimations

    It might be related somehow to setting the correct path, but as I have copied the assetbundle folder afterwards to Xcode project, the problem persists.

  • lase
    lase over 4 years
    To add to Programmer's excellent answer - be aware that the box to the right of the AssetBundle "name" box in the editor acts as an extension. If you set an extension in the editor, you'll need to load Application.streamingAssetsPath + "/AssetBundle/" + assetbunlenameWithoutExtension + myAssetBundleExtension; for Unity to find it. It's a bit tricky because inside the Editor it still looks like there is a copy without an extension, but there isn't, which you can see plainly if you navigate to that location in Finder/Explorer.
  • Reahreic
    Reahreic almost 4 years
    Nice clear example, the thing that confuses me about AssetBundles (admittedly i need to experiment with it) is if i have a prefab that's assigned to an assetbundle do i still drag it into a scene and use it like that or do i need to forever more instantiate it into the scene via code only, to avoid duplicate packaging at app build time. Alternately if a scene is assigned to an asset bundle it'self, do i exclude that scene from the traditional build process. (File > BuildSettings > Scenes In Build)
  • Johny
    Johny almost 3 years
    @Programmer Thank you for the extended explanation. Is it possible to add custom files (SQLite database) in AssetBundle?