Unity5-ABSystem(3): AssetBundle Loading

Keywords: Android Unity Mac iOS

Reprinted from: http://blog.csdn.net/lodypig/article/details/51872595

Unity Special Path

When loading AssetBundle, Unity has a lot of special power to give the path of AssetBundle file. Here are some paths related to loading. These paths are different on different platforms and may contain project or company names. The similar myProject and myCompany appearing below should be replaced by the corresponding name of your project.

Resources

Resources files can be either in the root directory or in subdirectories, as long as they are called Resources. All resources under the Resources directory will be packaged into the archive of the game storage resources, and the Resources directory will no longer exist in the application, but the path used under the Resources will still be used when loading.  
All resources in this directory will be compressed, read-only and not written, and loaded using the Resources.Load() interface.

StreamingAssetsPath

The Streaming Assets directory must be in the root directory, where all resources will be packaged into the game. Unlike the Resources directory, resources in the Streaming Assets directory will not be compressed, and they are also read-only and not writable. Unity basically does not provide a way to read resources directly from this path. Only www can load audioClip, text, and binary files. But Unity provides a way to load AssetBundle from that directory, where we usually store AssetBundle files directly. This path can be accessed through Application. streaming Assets Path.  
   
Streaming Assets Path for Platforms:
  Win: E:/myProj/Assets/StreamingAssets 
  Mac : /myProj/Assets/StreamingAssets 
  Andorid: jar:file:///data/app/com.myCompany.myProj-1/base.apk!/assets 
  iOS: /var/containers/Application/E5543D66-83F3-476D-8A8F-49D5332B3763/myProj.app/Data/Raw

PersistentDataPath

This directory is the application sandbox directory, which will not appear until the application is installed. The directory is unique in that it can be written, so we usually store the downloaded AssettBundle here. Access using Application. persistent DataPath.  
Persistent Data Path Path Path for each platform:
  Win: C:/Users/lodypig/Appdata/LocalLow/myCompany/myProj 
  Mac : /Users/lodypig/Library/Application Support/myCompany/myProj 
  Andorid: /data/data/com.myCompany.myProj/files 
  iOS: /var/mobile/Containers/Data/Appliction/A112252D-6B0E-459Z-9D49-CD3EAC6D47D/Documents

DataPath

Application directory, namely Assets directory. Access using Appliction.dataPath.  
Data Path Path Path for Platforms:
  Win: E:/myProj/Assets 
  Mac : /myProj/Assets/ 
  Andorid: /data/app/com.myCompany.myProj-1/base.apk! 
  iOS: /var/containers/Application/E5543D66-83F3-476D-8A8F-49D5332B3763/myProj.app/Data

Synchronous loading

Core function

AssetBundle.LoadFromFile(string path);

Unable to load synchronously on Android platform

  Android Under the platform, loading directly with Application. streaming Assets Path will report an error of cannot open archive, because the path is wrong when loading. You can go back and see that the Application. streaming Assets Path on Android starts with jar:file:// unlike everyone else. If this section is removed, it will be able to load normally. When removed, it is equivalent to Application.dataPath + "! assets", so in the ____________ Android Next, we use this path to load.

Example

public class AssetBundleLoader {
    // Declare Streaming Assets Path paths based on different platforms
    public static readonly string STREAMING_ASSET_PATH =
        #if UNITY_ANDROID
             Application.dataPath + "!assets";   // Android platform
        #else  
             Application.streamingAssetsPath;  // Other platforms
        #endif

    // Loading from Streaming Assets Path
    public static AssetBundle LoadFromStreamingAssetsPath(string assetbundle) {
        return AssetBundle.LoadFromFile(STREAMING_ASSET_PATH + "/" + assetbundle);
    }

    // Persistant DataPath Loading
    public static AssetBundle LoadFromPersistantDataPath(string assetbundle) {
        return AssetBundle.LoadFromFile(Application.persistentDataPath+ "/" + assetbundle)
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Asynchronous loading

Core function

AssetBundle.LoadFromFileAsync(string path);

Example

public class AssetBundleLoader : MonoBehaviour {
    // Declare Streaming Assets Path as above
    public static readonly string STREAMING_ASSET_PATH = ...
    // Realization of Association
    static IEnumerator LoadAsyncCoroutine(string path, Action<AssetBundle> callback) {
        AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(path);
        yield return abcr;        
        callback(abcr.assetBundle);
    }

    // Open Association
    static bool LoadAssetbundleAsync(string finalPath, Action<AssetBundle> callback)
    {
        StartCoroutine(LoadAsyncCoroutine(finalPath, callback));
    }

    // Asynchronous loading from Streaming Assets Path
    public static AssetBundle LoadFromStreamingAssetsPathAsync(string assetbundle) {
        return LoadAssetbundleAsync(STREAMING_ASSET_PATH + "/" + assetbundle);
    }

    // Persistant DataPath asynchronous loading
    public static AssetBundle LoadFromPersistantDataPathAsync(string assetbundle) {
        return LoadAssetbundleAsync(Application.persistentDataPath+ "/" + assetbundle)
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

WWW Asynchronous Loading

In addition to using AssetBundle.LoadFromFileAsync, you can also use www to load AssetBundle asynchronously.

public class AssetBundleLoader : MonoBehaviour {
    // Streaming Asset Platform Paths During WWW Loading
    public static readonly string WWW_STREAM_ASSET_PATH =
        #if UNITY_ANDROID
            Application.streamingAssetsPath;      // Android uses this directly
        #elif 
            "file://" + Application.streamingAssetsPath;  // Adding file to other platforms//
        #endif


    // Implementation of www protocol
    static IEnumerator LoadFromWWWCoroutine(string path, Action<AssetBundle> callback)
    {
        WWW www = new WWW(path);
        yield return www;
        callback(www.assetBundle);
        www.Dispose();
        www = null;
    }

    //Open Association
    static bool LoadAssetbundleAsync(string finalPath, Action<AssetBundle> callback)
    {
        StartCoroutine(LoadFromWWWCoroutine(finalPath, callback));
    }

    // Asynchronous loading from Streaming Assets Path
    public static AssetBundle LoadFromStreamingAssetsPathAsync(string assetbundle) {
        return LoadAssetbundleAsync(STREAMING_ASSET_PATH + "/" + assetbundle);
    }

    // Persistant DataPath asynchronous loading
    public static AssetBundle LoadFromPersistantDataPathAsync(string assetbundle) {
        return LoadAssetbundleAsync(Application.persistentDataPath+ "/" + assetbundle)

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

Resource loading

Core function

    AssetBundle.LoadAsset(string assetName, Type resType);
    AssetBundle.LoadAssetAsync(string assetName, Type resType);
  • 1
  • 2
  • 1
  • 2

There's nothing to say, just code it. It is also synchronous and asynchronous.

public UnityEngine.Object Load(AssetBundle assetbundle, string assetName, Type resType)
{
    return assetBundle.LoadAsset(assetName, resType);
}

IEnumerator LoadAssetAsyncCoroutine(AssetBundle ab, string name, Type resType, Action<UnityEngine.Object> callback)
{
        AssetBundleRequest request = ab.LoadAssetAsync(name, resType);   

        // Waiting for loading to complete
        while (!request.isDone)
        {
            yield return false;
        }
    callback(request.asset);   // Callback layer
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

In addition to these, there are Load All Assets Async, Load All Assets and other methods, for details see Unity official website.

Posted by stefan63 on Fri, 29 Mar 2019 02:00:28 -0700