Classes | Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Properties | Events | List of all members
BundleManager Class Reference

Detailed Description

Loads and tracks asset bundles at runtime.

One instance manages one IBundleManifest worth of content. It is safe to support multiple IBundleManifests with additional instances.

Getting started:

  1. Make a BundleManager (either in Editor or runtime).
  2. Assign a Manifest (see Manifests.IBundleManifest)
  3. Request a bundle or asset via BundleManager
  4. Use said bundle or asset in your game
  5. Unload the bundle via UnloadAssetBundle
  6. Repeat loading more bundles and assets from the Manifest.

We offer three levels of request API:

It is possible to swap out IBundleManifests while retaining the same BundleManager. This is useful for changing datasets while your app is running.

All bundle names are passed in as "sanitized", meaning no Variants (bundleName.variant) or hashes (bundleName_123123098). It is the manifest's job to translate those to the current Variant and hash as needed.

When naming bundles, avoid using periods (confuses Variant system). Adding slashes to bundle names is a good way of organizing bundles, creates 'folders' of them. Be careful however of double slashes together (//), that messes with the menu displays. Do not use underscores in variant names either.

When errors occur in a Load/Preload, they must still be balanced by UnloadAssetBundle so that this system knows the caller has seen the error.

Reminder: you can add built bundles to your Project's StreaminAssets folder to embed a set of them in your shipped binary. They are always automatically searched when loading bundles. This is a great way to "pre-download" bundle content while still maintaining the ability to override them in production.

Inheritance diagram for BundleManager:

Mid-Level API

ILoadAsset  LoadAsset (string assetBundleName, string assetName, System.Type type, Priority priority=Priority.Immediate)
 
ILoadAsset  LoadAsset< T > (string assetBundleName, string assetName, Priority priority=Priority.Immediate)
 
IOperation  LoadLevel (string assetBundleName, string levelName, bool isAdditive, Priority priority=Priority.Immediate)
 

Low-level API

ILoadBundle  LoadBundle (string assetBundleName, Priority priority=Priority.WifiOnly)
 
IGetVersion  GetBundleVersion (string assetBundleName)
 
IOperation  PreloadBundle (string assetBundleName, Priority priority=Priority.WifiOnly)
 
void  UnloadBundle (string assetBundleName)
 
void  UnloadUnusedBundles ()
 
Coroutine  UnloadUnusedAssets ()
 

Tools for IManifestLoaders

Coroutine  LoadManifest (string absolutePath, int version, IOperation loadOp)
 
static IEnumerator  LoadManifest (BundleManager manager, string absolutePath, int version, int retries, float retryDelay, IOperation loadOp)
 
static bool  IsNonRetryableErrorFromWWW (WWW www)
 
static int  ParseErrorCodeFromWWW (WWW www)
 

Debugging

static ILogger  Logger
 
System.Text.StringBuilder  DumpState (System.Text.StringBuilder dest=null)
 
AssetBundle[]  GetLoadedBundles ()
 

Classes

class   ManagerSettings
 

Public Types

enum   Priority { WifiOnly, Low, Immediate }
 
enum   UnloadMode { Immediate, Delayed, AutomaticDelayed }
 
enum   BundleState {
  Waiting, SelfNetworking, ChildrenNetworking, SelfOpening,
  ChildrenOpening, DoingCallbacks, Complete
}
 

Public Member Functions

delegate void  DownloadCompleteProc (string key, float[] stats)
 
IOperation  BustCacheIfNeeded (string prefKey, int currentVersion)
 
void  ReworkShaders ()
 

Static Public Member Functions

static string  SanitizeBundleName (string name)
 
static string  GetUrlPath (string url)
 
static string  GetPlatformForAssetBundles (RuntimePlatform platform)
 
static string  GetPlatformForAssetBundles ()
 
static string  GetLibCompiledTarget ()
 

Public Attributes

ManagerSettings  Settings
 

Properties

uint  AmountToProcess [get]
 
uint  AmountProcessed [get]
 
IBundleManifest  Manifest [get, set]
 
static bool  SimulateAssetBundleInEditorPref [get, set]
 
static bool  SimulateAssetBundleInEditor [get]
 

Events

DownloadCompleteProc  DownloadComplete
 
Action  DeletedEvent
 

Member Enumeration Documentation

◆ BundleState

enum BundleState
strong

Each state a bundle goes through in the loading process.

Corresponds with values DownloadCompleteProc returns. Do not assume this is set in stone!

◆ Priority

enum Priority
strong

Each of these represents a separate download queue.

Enumerator
WifiOnly 

The user will need this eventually, but only if we are on a non-metered connection.

Low 

The user will need this eventually, but we will need it even on a cell network.

Avoid this if possible, in favor of WifiOnly

Immediate 

The user is waiting on it right now

◆ UnloadMode

enum UnloadMode
strong

How to deal with unloading bundles when the last reference is unloaded

Enumerator
Immediate 

Bundle is immediately unloaded when ref count is zero

Delayed 

They are unloaded when ref count is zero and UnloadUnused() is called

AutomaticDelayed 

They are unloaded a few seconds after the ref count reaches zero

Member Function Documentation

◆ BustCacheIfNeeded()

IOperation BustCacheIfNeeded ( string  prefKey,
int  currentVersion 
)
inline

Bust local cache if passed version number doesn't match what's in PlayerPrefs.

Should be done once on startup, before anything is loaded.

We had a situation where the asset bundle data was junk on live clients. We fixed what was on the server just fine, but the file hashes that Unity uses only includes the source assets, not the resulting bundle. This means the clients would always see the damaged bundles in the cache and never reach out for updated ones.

By increasing the following constant(preferably for a single platform only), we will dump the local cache and force-get an all new bundle set. For a new device, there will be no local cache data anyway, so nothing is lost/wasted.

◆ DownloadCompleteProc()

delegate void DownloadCompleteProc ( string  key,
float[]  stats 
)

Record stats of a completed (or failed) download.

Parameters
key typically the bundle id
stats each entry is how long in seconds that the download was in each BundleState

◆ DumpState()

System.Text.StringBuilder DumpState ( System.Text.StringBuilder  dest = null )
inline

Snapshot the state for debugging purposes

◆ GetBundleVersion()

IGetVersion GetBundleVersion ( string  assetBundleName )
inline

Get a string representing the version of the bundle.

Avoid using/relying on this!!! Useful for comparing that a previously loaded version is same vs. different.

Parameters
assetBundleName Sanitized bundle name.
Returns
The bundle version or null if not ready.

◆ GetLibCompiledTarget()

static string GetLibCompiledTarget ( )
inlinestatic

What platform was this library built for?

This is for debugging purposes only!

Returns

◆ GetLoadedBundles()

AssetBundle [] GetLoadedBundles ( )
inline

purely for debugging only

◆ GetPlatformForAssetBundles() [1/2]

static string GetPlatformForAssetBundles ( )
inlinestatic

Make consistent strings between runtime and build-time for what the "current platform" is.

In the Editor, will automatically get the current target platform for you.

Returns
string or null if not known.

◆ GetPlatformForAssetBundles() [2/2]

static string GetPlatformForAssetBundles ( RuntimePlatform  platform )
inlinestatic

Make consistent strings between runtime and build-time for what the "current platform" is.

Parameters
platform As gotten from Application.platform
Returns
string or null if not known.

◆ GetUrlPath()

static string GetUrlPath ( string  url )
inlinestatic

Get the path of the URL including the trailing slash

Parameters
url http://this/that/other/file.what
Returns
http://this/that/other/

◆ IsNonRetryableErrorFromWWW()

static bool IsNonRetryableErrorFromWWW ( WWW  www )
inlinestatic

Is this an error that there is no point in retrying?

On a 403 (Amazon s3 uses those) or FnF, drop out immediately.

◆ LoadAsset()

ILoadAsset LoadAsset ( string  assetBundleName,
string  assetName,
System.Type  type,
Priority  priority = Priority.Immediate 
)
inline

Load asset from the given assetBundle.

Remember to UnloadBundle when you are done with the content!

Parameters
assetBundleName Sanitized bundle name.
assetName Name of asset, without extension.
type Expected asset type, ex: GameObject, Texture2d. Cannot directly request Components!
priority How quickly is this needed?

◆ LoadAsset< T >()

ILoadAsset LoadAsset< T > ( string  assetBundleName,
string  assetName,
Priority  priority = Priority.Immediate 
)
inline

Load asset from the given assetBundle.

Remember to UnloadBundle when you are done with the content!

Parameters
assetBundleName Sanitized bundle name.
assetName Name of asset, without extension.
priority How quickly is this needed?

◆ LoadBundle()

ILoadBundle LoadBundle ( string  assetBundleName,
Priority  priority = Priority.WifiOnly 
)
inline

Load a bundle directly.

Also preloads dependent bundles.

Remember to UnloadBundle when you are done with the content!

Parameters
assetBundleName Sanitized bundle name.
priority How quickly is this needed?

◆ LoadLevel()

IOperation LoadLevel ( string  assetBundleName,
string  levelName,
bool  isAdditive,
Priority  priority = Priority.Immediate 
)
inline

Load level from the given assetBundle.

Remember to UnloadBundle when you are done with the content!

Parameters
assetBundleName Sanitized bundle name.
levelName Name of level.
priority How quickly is this needed?
isAdditive Once loaded, should it replace the current scene immediately? Otherwise it is added to the current scene.

◆ LoadManifest() [1/2]

static IEnumerator LoadManifest ( BundleManager  manager,
string  absolutePath,
int  version,
int  retries,
float  retryDelay,
IOperation  loadOp 
)
inlinestatic

Utility to load a directory object.

Absolutely intentional that it's static, as it should not rely on any current manager state.

Parameters
loadOp Caller must pass in a response object (typically ILoadAssetFullAsync) already prepared to accept the manifest object
absolutePath Path passed to WWW as 'source url'
version Cache version. Using a different value here forces WWW to ignore a locally cached version of the data.
manager Target manager, only used for the loadOp
retries How many times to attempt download. Minimum 1.
retryDelay How long to wait between retries. Special value<0 is double each retry.

◆ LoadManifest() [2/2]

Coroutine LoadManifest ( string  absolutePath,
int  version,
IOperation  loadOp 
)
inline

Load a manifest, using this BundleManager to do it.

Parameters
loadOp Caller must pass in a response object (typically ILoadAssetFullAsync) already prepared to accept the manifest object
absolutePath Path passed to WWW as 'source url'
version Cache version. Using a different value here forces WWW to ignore a locally cached version of the data.

◆ ParseErrorCodeFromWWW()

static int ParseErrorCodeFromWWW ( WWW  www )
inlinestatic

Work out what HTTP error was returned, if any.

Only really valid after WWW completes the request.

Parameters
www
Returns
code or -1 (no error reported)

◆ PreloadBundle()

IOperation PreloadBundle ( string  assetBundleName,
Priority  priority = Priority.WifiOnly 
)
inline

Preloads the bundle without loading the content

Also preloads dependent bundles.

Remember to UnloadBundle when you are done waiting for the result!

Parameters
assetBundleName Sanitized bundle name.
priority How quickly is this needed?

◆ ReworkShaders()

void ReworkShaders ( )
inline

in Editor only, after each item loads, check for new shaders.

Deal with the fact that shaders are embedded in asset bundles and will use fallbacks in the Editor. Like an iOS asset bundle will play fine on device, but the Editor will draw everything in pink "no shader" colors. This bit of code will replace each shader reference with the Editor versions.

This is done automatically for you when bundles are loaded, but you can call this to do an extra trigger. Safe to call outside the Editor, it's a NOP.

◆ SanitizeBundleName()

static string SanitizeBundleName ( string  name )
inlinestatic

Take a bundle name and remove bad things like underscores.

Parameters
name
Returns

◆ UnloadBundle()

void UnloadBundle ( string  assetBundleName )
inline

Unload a bundle, and all its dependencies.

Parameters
assetBundleName Sanitized bundle name.

◆ UnloadUnusedAssets()

Coroutine UnloadUnusedAssets ( )
inline

Wrapper for Resources.UnloadUnusedAssets()

Never call Unity's version directly, use this. This makes sure that no loads are going on at the same time as an unload. What would happen is a bunch of errors about scripts missing on gameObjects, which is not actually true.

Returns
Caller must wait for a coroutine instead of original using AsyncOperation, sorry.

◆ UnloadUnusedBundles()

void UnloadUnusedBundles ( )
inline

Anything unused, unload it now.

Typically only needed in Delayed mode.

Member Data Documentation

◆ Logger

ILogger Logger
static

Assign a logging handler

◆ Settings

ManagerSettings Settings

Do not change these settings after your first SetSourceURL().

Property Documentation

◆ AmountProcessed

uint AmountProcessed
get

How much data has been downloaded since startup? Perfect for progress bars.

How much has completed. How much is planned is in AmountToProcess.

◆ AmountToProcess

uint AmountToProcess
get

How much data we're going to download.

Perfect for progress bars.

How much we need to process. Eventually AmountProcessed will match this.

◆ Manifest

IBundleManifest Manifest
getset

The current directory

◆ SimulateAssetBundleInEditor

bool SimulateAssetBundleInEditor
staticget

Flag to indicate if we want to simulate assetBundles in Editor without actually building them.

To prevent confusion, we don't allow write mode. Use SimulateAssetBundleInEditorPref.

◆ SimulateAssetBundleInEditorPref

bool SimulateAssetBundleInEditorPref
staticgetset

Pref value for simulation in Editor

This is what you write to change the value. Use SimulateAssetBundleInEditor for indicating real state.

Event Documentation

◆ DeletedEvent

Action DeletedEvent

Get notified when this BundleManager is deleted by Unity