Unity5-ABSystem(三):AssetBundle加载

1 篇文章 0 订阅

  加载一事,就要先从路径说起了。

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);

  
  
  • 1

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

  安卓平台下,直接使用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
<span class="hljs-comment">// 从StreamingAssetsPath加载</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> AssetBundle <span class="hljs-title">LoadFromStreamingAssetsPath</span>(<span class="hljs-keyword">string</span> assetbundle) {
    <span class="hljs-keyword">return</span> AssetBundle.LoadFromFile(STREAMING_ASSET_PATH + <span class="hljs-string">"/"</span> + assetbundle);
}

<span class="hljs-comment">// PersistantDataPath加载</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> AssetBundle <span class="hljs-title">LoadFromPersistantDataPath</span>(<span class="hljs-keyword">string</span> assetbundle) {
    <span class="hljs-keyword">return</span> AssetBundle.LoadFromFile(Application.persistentDataPath+ <span class="hljs-string">"/"</span> + assetbundle)
}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19


异步加载

核心函数

AssetBundleCreateRequest AssetBundle.LoadFromFileAsync(string path, uint crc = 0, ulong offset = 0);

 
 
  • 1

示例

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);
    }
<span class="hljs-comment">// 开启协程</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">bool</span> LoadAssetbundleAsync(<span class="hljs-keyword">string</span> finalPath, Action&lt;AssetBundle&gt; callback)
{
    StartCoroutine(LoadAsyncCoroutine(finalPath, callback));
}

<span class="hljs-comment">// 从StreamingAssetsPath异步加载</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> AssetBundle <span class="hljs-title">LoadFromStreamingAssetsPathAsync</span>(<span class="hljs-keyword">string</span> assetbundle) {
    <span class="hljs-keyword">return</span> LoadAssetbundleAsync(STREAMING_ASSET_PATH + <span class="hljs-string">"/"</span> + assetbundle);
}

<span class="hljs-comment">// PersistantDataPath异步加载</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> AssetBundle <span class="hljs-title">LoadFromPersistantDataPathAsync</span>(<span class="hljs-keyword">string</span> assetbundle) {
    <span class="hljs-keyword">return</span> LoadAssetbundleAsync(Application.persistentDataPath+ <span class="hljs-string">"/"</span> + 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

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
<span class="hljs-comment">// www协程实现</span>
<span class="hljs-keyword">static</span> IEnumerator LoadFromWWWCoroutine(<span class="hljs-keyword">string</span> path, Action&lt;AssetBundle&gt; callback)
{
    WWW www = <span class="hljs-keyword">new</span> WWW(path);
    <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> www;
    callback(www.assetBundle);
    www.Dispose();
    www = <span class="hljs-keyword">null</span>;
}

<span class="hljs-comment">//开启协程</span>
<span class="hljs-keyword">static</span> <span class="hljs-keyword">bool</span> LoadAssetbundleAsync(<span class="hljs-keyword">string</span> finalPath, Action&lt;AssetBundle&gt; callback)
{
    StartCoroutine(LoadFromWWWCoroutine(finalPath, callback));
}

<span class="hljs-comment">// 从StreamingAssetsPath异步加载</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> AssetBundle <span class="hljs-title">LoadFromStreamingAssetsPathAsync</span>(<span class="hljs-keyword">string</span> assetbundle) {
    <span class="hljs-keyword">return</span> LoadAssetbundleAsync(STREAMING_ASSET_PATH + <span class="hljs-string">"/"</span> + assetbundle);
}

<span class="hljs-comment">// PersistantDataPath异步加载</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> AssetBundle <span class="hljs-title">LoadFromPersistantDataPathAsync</span>(<span class="hljs-keyword">string</span> assetbundle) {
    <span class="hljs-keyword">return</span> LoadAssetbundleAsync(Application.persistentDataPath+ <span class="hljs-string">"/"</span> + 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

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

资源加载

核心函数

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

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

// 同步
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);

    <span class="hljs-comment">// 等待加载完成</span>
    <span class="hljs-keyword">while</span> (!request.isDone)
    {
        <span class="hljs-keyword">yield</span> <span class="hljs-keyword">return</span> <span class="hljs-keyword">false</span>;
    }
callback(request.asset);   <span class="hljs-comment">// 回调上层</span>

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值