zoukankan      html  css  js  c++  java
  • (非原创)AssetBundle加载

    Unity特殊路径

      在加载AssetBundle时,要给出AssetBundle文件路径,Unity有很多特殊路径,这里列出部分与加载相关的路径。这些路径在不同平台下是不相同的,并可能包含项目或公司名字。下文中出现的类似myProject、myCompany应换成你工程所对应的名字。

    Resources

      Resources文件可以在根目录下,也可以在子目录下,只要叫Resources就好。Resources目录下所有资源将被打包进游戏存放资源的archive中,Resources目录在应用中也就不复存在,但加载时仍使用曾在Resource下的路径。 
      该目录下所有资源会被压缩,只读不可写,使用Resources.Load()接口加载。

    StreamingAssetsPath

      StreamingAssets目录必须在Assets根目录下,该目录下所有资源也会被打包到游戏里,不同于Resources目录,该目录下的资源不会进行压缩,同样是只读不可写的。Unity基本也没有提供从该路径下直接读取资源的方法,只有www可以加载audioClip、texture和二进制文件。但Unity提供了从该目录加载AssetBundle的方法,我们一般直接在这个目录下存放AssetBundle文件。可以通过Application.streamingAssetsPath访问该路径。 
       
      各平台StreamingAssets路径打印: 
      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

      该目录为应用程序沙盒目录,应用程序安装后才会出现。该目录独特之处在于是可写的,所以我们一般将下载的AssetBundle存放于此。使用Application.persistentDataPath访问。 
      各平台PersistentDataPath路径打印: 
      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

      应用程序目录,即Assets目录。使用Appliction.dataPath访问。 
      各平台DataPath路径: 
      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

    同步加载

    核心函数

    AssetBundle AssetBundle.LoadFromFile(string path);
    

    安卓平台下不能同步加载问题

      安卓平台下,直接使用Application.streamingAssetsPath进行加载会报cannot open archive的错误,原因是加载时路径不对。可以返回上面看一下,安卓平台下Application.streamingAssetsPath以jar:file://开头,跟其他人都不一样。将这段去掉就能够正常加载。而去掉后等价于Application.dataPath + “!assets”,所以在Android下我们用该路径加载。

    示例

    public class AssetBundleLoader {
        // 根据不同平台,声明StreamingAssetsPath路径
        public static readonly string STREAMING_ASSET_PATH =
            #if UNITY_ANDROID
                 Application.dataPath + "!assets";   // 安卓平台
            #else  
                 Application.streamingAssetsPath;  // 其他平台
            #endif
    
        // 从StreamingAssetsPath加载
        public static AssetBundle LoadFromStreamingAssetsPath(string assetbundle) {
            return AssetBundle.LoadFromFile(STREAMING_ASSET_PATH + "/" + assetbundle);
        }
    
        // PersistantDataPath加载
        public static AssetBundle LoadFromPersistantDataPath(string assetbundle) {
            return AssetBundle.LoadFromFile(Application.persistentDataPath+ "/" + assetbundle)
        }
    }

    异步加载

    核心函数

    AssetBundleCreateRequest AssetBundle.LoadFromFileAsync(string path, uint crc = 0, ulong offset = 0);
    public class AssetBundleLoader : MonoBehaviour {
        // 声明StreamingAssetsPath如上
        public static readonly string STREAMING_ASSET_PATH = ...
        // 协程实现
        static IEnumerator LoadAsyncCoroutine(string path, Action<AssetBundle> callback) {
            AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(path);
            yield return abcr;        
            callback(abcr.assetBundle);
        }
    
        // 开启协程
        static bool LoadAssetbundleAsync(string finalPath, Action<AssetBundle> callback)
        {
            StartCoroutine(LoadAsyncCoroutine(finalPath, callback));
        }
    
        // 从StreamingAssetsPath异步加载
        public static AssetBundle LoadFromStreamingAssetsPathAsync(string assetbundle) {
            return LoadAssetbundleAsync(STREAMING_ASSET_PATH + "/" + assetbundle);
        }
    
        // PersistantDataPath异步加载
        public static AssetBundle LoadFromPersistantDataPathAsync(string assetbundle) {
            return LoadAssetbundleAsync(Application.persistentDataPath+ "/" + assetbundle)
        }
    }

    WWW异步加载

      除了使用AssetBundle.LoadFromFileAsync外,还可以使用www异步加载AssetBundle。

    public class AssetBundleLoader : MonoBehaviour {
        // WWW加载时StreamingAsset各平台路径
        public static readonly string WWW_STREAM_ASSET_PATH =
            #if UNITY_ANDROID
                Application.streamingAssetsPath;      // 路径与上面不同,安卓直接用这个
            #elif 
                "file://" + Application.streamingAssetsPath;  // 反而其他平台加file://
            #endif
    
    
        // www协程实现
        static IEnumerator LoadFromWWWCoroutine(string path, Action<AssetBundle> callback)
        {
            WWW www = new WWW(path);
            yield return www;
            callback(www.assetBundle);
            www.Dispose();
            www = null;
        }
    
        //开启协程
        static bool LoadAssetbundleAsync(string finalPath, Action<AssetBundle> callback)
        {
            StartCoroutine(LoadFromWWWCoroutine(finalPath, callback));
        }
    
        // 从StreamingAssetsPath异步加载
        public static AssetBundle LoadFromStreamingAssetsPathAsync(string assetbundle) {
            return LoadAssetbundleAsync(STREAMING_ASSET_PATH + "/" + assetbundle);
        }
    
        // PersistantDataPath异步加载
        public static AssetBundle LoadFromPersistantDataPathAsync(string assetbundle) {
            return LoadAssetbundleAsync(Application.persistentDataPath+ "/" + assetbundle)
    }

    以上三种方式都可以从一个完整的StreamingAssetsPath下,加载到一个AssetBundle对象。接着我们要从AssetBundle对象中,加载出可爱的资源们。

    资源加载

    核心函数

    Object AssetBundle.LoadAsset(string assetName, Type resType);
        AssetBundleRequest AssetBundle.LoadAssetAsync(string assetName, Type resType);

    没什么好说的,上代码吧,看参数名和接口应该就能明白。同样是同步和异步两种方式。

    // 同步
    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);   
    
            // 等待加载完成
            while (!request.isDone)
            {
                yield return false;
            }
        callback(request.asset);   // 回调上层
    }

    除了这些外,加载资源还有LoadAllAssetsAsync、LoadAllAssets等方法,加载AssetBundle还有LoadFromMemory、LoadFromMemoryAsync方法。原理类似,不再赘述。详情见Unity官方网站

  • 相关阅读:
    Python中的除法
    使用Windows Live Writer 2012和Office Word 2013 发布文章到博客园全面总结
    单例模式(Singleton)的6种实现
    Linux关机命令总结
    Java中构造函数执行顺序的问题
    SVN四部曲之SVN命令精通
    SVN四部曲之SVN简单使用教程入门
    SVN四部曲之SVN使用详解进阶
    用正则表达式判断一个二进制数是否能被3整除
    栈帧%ebp,%esp详解
  • 原文地址:https://www.cnblogs.com/VindyLeong/p/6513436.html
Copyright © 2011-2022 走看看