Click To Download Full Source Code
Asset Bundles are files that contain assets. Various assets like models, textures, audio files, etc. can be put in a bundle and exported to be used later. They let you stream assets using the WWW class so you can download the assets from a server at runtime too. Asset Bundles can be used to setup DLCs for games or just to reduce the initial download size.
The Asset Bundle workflow is as follows:
- Create Asset Bundle in Unity Editor.
- Upload it on a server.
- Download and use it during runtime.
Creating Asset Bundles:
Here we have got 3 watercraft models, namely, ‘Houseboat’, ‘Ship’, and ‘Speedboat’, in the scene. You can use some primitives like Cube, Sphere, Capsule, Cylinder, etc. for this example. Drag and drop the models in the scene and then into the Prefabs folder inside the Assets folder to create the prefabs for them. These prefabs will be exported in the bundle. The names of the prefabs are important because that’s what will be used to load them when required.
Now, create and put the following script in the Editor folder in Unity.
using UnityEngine; using System.Collections; using UnityEditor; public class CreateAssetBundles : Editor { [MenuItem("Assets/Create Asset Bundle")] static void ExportBundle() { string bundlePath = "Assets/AssetBundle/watercraft.unity3d"; Object[] selectedAssets = Selection.GetFiltered(typeof(Object), SelectionMode.Assets); BuildPipeline.BuildAssetBundle(Selection.activeObject, selectedAssets, bundlePath,BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets,BuildTarget.StandaloneOSXUniversal); } } }
The ExportBundle() method gets all the selected assets in the project window and creates an asset bundle containing the selected assets at the path bundlePath. You can change the BuildTarget depending on your platform.
Select all the prefabs and click on Create Asset Bundle in the context menu. This will create the asset bundle in the AssetBundle folder. This might take some time depending on the number and size of the assets.
Uploading Asset Bundles:
Open your Explorer/Finder, navigate to the folder containing the Asset Bundle you just created and upload the .unity file on a server. I used Dropbox for the sake of simplicity.
Once you’re done, get the link to the file. Make sure the link gets the file downloaded and doesn’t just launch the webpage for the file.
For example, Dropbox gives you a url that will look something like this: https://www.dropbox.com/s/xxxxxxxxxxxxxxx/watercraft.unity3d?dl=0. But using this url will result in an error. Replace ‘dl=0’ with ‘dl=1’ in the link to get the actual download link. That should work.
Downloading Asset Bundles:
Below is a slightly modified version of the actual Asset Downloader script,
Click To Downloading Asset Bundles
using UnityEngine; using System.Collections; using UnityEngine.UI; public class AssetDownloader : MonoBehaviour { public string url; GameObject waterCraftGO; public Text loadingText; public Transform spawnPos; IEnumerator LoadBundle(string watercraftName) { while (!Caching.ready) { yield return null; } //Begin download WWW www = WWW.LoadFromCacheOrDownload (url, 0); yield return www; //Load the downloaded bundle AssetBundle bundle = www.assetBundle; //Load an asset from the loaded bundle AssetBundleRequest bundleRequest = bundle.LoadAssetAsync (watercraftName, typeof(GameObject)); yield return bundleRequest; //get object GameObject obj = bundleRequest.asset as GameObject; waterCraftGO = Instantiate(obj, spawnPos.position, Quaternion.identity) as GameObject; loadingText.text = ""; bundle.Unload(false); www.Dispose(); } public void Load(string watercraftName) { if(waterCraftGO) { Destroy(waterCraftGO); } loadingText.text = "Loading..."; StartCoroutine(LoadBundle(watercraftName)); } }
The LoadBundle() Coroutine downloads the bundle if it isn’t already downloaded or if it doesn’t already exist in the cache by using the LoadFromCacheOrDownload() method. The first parameter is the url to your bundle file on the server and the second one is the version.
Next, we load a specific asset from the bundle using this statement:
AssetBundleRequest request = bundle.LoadAssetAsync (watercraftName, typeof(GameObject));
After loading, we Instantiate the object as a game object in the scene.
Add the AssetDownloader.cs script to an empty game object in your scene and set it up as follows:
I added a Transform field and a UI Text field to have a spawn position and a loading text available.
Create 3 UI buttons in the Canvas and use them to call the AssetDownloader.Load(string watercraftName) method. Make sure you pass the correct string parameter (the exact names of the prefabs that are in the bundle)
Play the scene. Clicking on any on the buttons should download the respective asset and instantiate it in the scene. I added a little rotation script later to make it look good.
Initially, the download will take a few seconds. Once you download the bundle, it’s stored in the cache so you don’t need to download it over and over again. Hence, when you try to load an already downloaded asset, it will load the asset from the downloaded bundle in the cache.
Here’s a .gif.