This tech note will walk you through building an asset bundle, and using the bundle as an expansion file. Oculus supports uploading 1 APK file up to 1GB in size, and 1 expansion file, up to 4GB in size. When using the Split Application Binary feature in Unity, the engine outputs two expansion files, up to 2GB each. Android apps built with Unity 2017 are 32-bit, and thus cannot files larger than 2GB. However, building your own asset bundles as described here has a lot of advantages over the built-in method, including significant improvement in load times.
The only thing special about expansion files is their name and location on disk. Any file that follows the appropriate naming convention and is placed in the correct location can be treated like an expansion file.
Place large assets in bundle
Assign all assets that should be included in the expansion file to an asset bundle. Scenes that are included in the asset bundle should NOT be included in build settings. All large assets (such as videos) should only be referenced from these scenes.
Build the asset bundle
Asset bundles are going to have to be built from code. The simplest build script will look something like this:
using UnityEngine;
using UnityEditor;
public class BuildAssetBundles : MonoBehaviour {
[MenuItem("Build/Asset Bundles")]
public static void BuildBundles() {
string path = Application.dataPath + "/../AssetBundles/";
if (!System.IO.Directory.Exists(path)) {
System.IO.Directory.CreateDirectory(path);
}
BuildPipeline.BuildAssetBundles("AssetBundles", BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.Android);
}
}
Additional steps like automatically renaming the asset bundle can be added to the above code snippet. The above command will output several files, the only one you need is the actual asset bundle. The .manifest file is not needed.
Rename the bundle
The generated asset bundle has no extension, it's just a file name. Rename the asset bundle to match the expected formatting of the expansion file name. The expected naming format is:
main.<version>.<package>.obb
Where <version> and <package> are defined in the player settings. The bundle version will need to be increased each time a new build is uploaded.
Read Permission
The expansion file is probably going to be located on external storage. To allow Unity to read the file, add the READ_EXTERNAL_STORAGE permission to the Android manifest file.
Consider using a plugin to test if the app has permission to read from external storage. If it does not, the app can't load the levels found in the asset bundle.
Load the Asset Bundle
Before loading any scene that is located in the asset bundle, make sure that the actual bundle is loaded into memory. This call needs to be made only once, it's a good candidate to place somewhere in startup code that only executes when the game launches.
Because the bundle version changes with each build that is uploaded, it's best not to hard code the bundle path. Unity does not expose the bundle version to the Android runtime. One common approach to this is to generate a C# file every time a build is made as a pre-build step and write PlayerSettings.Android-bundleVersionCode to it as a static variable.
A more robust solution is to write a simple plugin which returns the expansion file path. The following Java code will return the name of the expansion file:
package com.oculus.versionhelper;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageInfo;
import android.os.Environment;
import java.io.File;
public class VersionHelper {
private Context mContext;
public VersionHelper(Context context) {
mContext = context;
}
public String GetExpansionFilePath() {
PackageManager pm = mContext.getPackageManager();
String name = mContext.getPackageName();
PackageInfo pi = null;
try {
pi = pm.getPackageInfo(name, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return "";
}
int version = pi.versionCode;
String storageDir = Environment.getExternalStorageDirectory().getAbsolutePath();
String packageName = mContext.getPackageName();
return storageDir + File.separator + "Android" + File.separator + "obb" + File.separator + "main." + version + "." + packageName + ".obb";
}
}
The C# script to call this helper function from within Unity:
using UnityEngine;
public static class VersionHelper {
private static string ACTIVITY_NAME = "com.unity3d.player.UnityPlayer";
private static string CONTEXT = "currentActivity";
private static string VERSION_HELPER_CLASS = "com.oculus.versionhelper.VersionHelper";
private static AndroidJavaObject versionHelper = null;
public static string ExpansionFileLocation {
get {
#if UNITY_ANDROID
if (versionHelper == null) {
AndroidJavaObject context = new AndroidJavaClass(ACTIVITY_NAME).GetStatic<AndroidJavaObject>(CONTEXT);
versionHelper = new AndroidJavaObject(VERSION_HELPER_CLASS , context);
}
return versionHelper.Call<string>("GetExpansionFilePath");
#else
return "";
#endif
}
}
}
With the plugin code above, loading the asset bundle becomes:
Uploading to one of the store channels needs to be done with the cli tool. Details on how to upload with the cli tool can be found here. Once uploaded to one of the release channels, the expansion file will be automatically downloaded to the correct location whenever the app is installed. Remember, each time you upload a new apk, the expansion file version has to increase.
Unity
Did you find this page helpful?
Explore more
Spatial Lingo: An Open Source App for AI-Assisted Language Practice with Everyday Objects
Discover Spatial Lingo, a new open source app from Meta that brings mixed reality and AI together to make practicing a new language fun and immersive.
Give Your App the Upper Hand: What’s New with Hand Tracking in v83
Learn how hand tracking in v83 delivers smoother performance, faster movement, and more natural interactions so you can design richer VR experiences with Meta Horizon OS.
All, Apps, Design, Games, Hand tracking, Quest, Unity, Unreal
Seamless Haptics for Sound Designers: Meta Haptics Studio Meets FMOD and Wwise
Bring audio and haptics together in one workflow. Learn how sound designers can use Meta Haptics Studio with FMOD and Wwise to design, preview, and integrate tactile feedback faster.