【AssetBundle】七:打包生成的manifest文件

我们在之前知道了AssetBundle打包的时候除了生成AssetBundle包之外,还会生成.manifest文件,我们把它称作配置文件。从事Android开发的同学们一定不会对.AndroidManifest文件陌生,所以我们习惯上也把AssetBundle打包的时候生成的.manifest文件成为该AssetBundle包的配置文件。

我们使用EditPlus打开配置文件看看:

【AssetBundle】七:打包生成的manifest文件

我们先来看看上图中指出的1、2、3:

1.CRC

说起CRC我们可能会有些陌生,但是说起MD5,恐怕大家都只要这玩意是干什么用的了。

MD5用于确保信息传输完整一致,也就是我们常说的校验码,CRC与MD5相同,属于校验文件方式的一种。资源包在使用之前首先要保证我接收到的包要完整吧,所以unity打包AssetBundle包,使用了CRC来进行校验。至于CRC与MD5有什么区别,我想这并不在我们讨论的范围之内,只需要了解一点:CRC用于通讯,MD5用于大容量存储,MD5更安全,CRC效率更高。

2.Assets:

这块区域包含的是这个AssetBundle包包含了哪些资源,我们可以看到有名为Wood texture floor_01的png图片和名为Wood texture floor_01的材质,同时,它们的路径也就很清楚的显示了出来。

3.Dependencies:

这个就是我们之前说的依赖信息了,unity在打包的时候会根据资源之间的依赖关系自动向这其中插入相关信息。

上图中因为是我们共享的图片和素材的AssetBundle包,所以在包含了图片和材质的信息之后,并不需要依赖其他的资源,所以依赖信息的位置为空,我们打开prefab的AssetBundle包的配置文件:

【AssetBundle】七:打包生成的manifest文件

我们可以看到球体prefab打包AssetBundle之后,配置文件中包含一个校验码,prefab的路径信息,最重要的是在最下方的依赖信息中,我们可以看到它依赖了我们刚刚查看的material包。

我们再来看看另外一个问题:

假如我在开发的时候,代码加载了AssetBundle包,但是包里依赖的资源我在工程里都存在,那么我需不需要加载依赖的包呢?

答案是需要的。

加载包并且实例化prefab对象的时候,我们只认依赖关系,依赖关系能为我们提供精确地加载目标,而不需要在工程里面挨个检索资源。

这就是另一个内容:我们在加载某个AssetBundle包的时候,如果它依赖别的AssetBundle包,那么我们最好在加载并使用它之前,先把依赖的包加载出来,否则可能导致材质丢失、要实例化的对象不存在等错误。

我们试验下:unity工程中有了材质和贴图,我们来加载球体:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LoadAssetsBundlePackage : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {
        //先将资源包加载进内存
        AssetBundle assetBundle = AssetBundle.LoadFromFile("AssetBundles/sphere.assetsbundle");
        //然后再加载prefab
        GameObject prefab = assetBundle.LoadAsset<GameObject>("Sphere");
        Instantiate(prefab);
    }
}

结果如下:

【AssetBundle】七:打包生成的manifest文件虽然本地有着材质和贴图,但是球体prefab并不会使用,它认准的是资源包中依赖的材质和贴图。

所以我们需要在加载球体的AssetBundle包之前先将材质和贴图的AssetBundle对象加载进内存中:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LoadAssetsBundlePackage : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {
        //先将材质和贴图的资源包加载进内存
        AssetBundle materialAssetBundle = AssetBundle.LoadFromFile("AssetBundles/material.assetsbundle");
        //接着将prefab资源包加载进内存
        AssetBundle sphereAssetBundle = AssetBundle.LoadFromFile("AssetBundles/sphere.assetsbundle");
        //然后再加载prefab
        GameObject prefab = sphereAssetBundle.LoadAsset<GameObject>("Sphere");
        Instantiate(prefab);
    }
}

结果我们可以发现,prefab能够正常的加载出来了:

【AssetBundle】七:打包生成的manifest文件

值得注意的是,我们在使用代码加载AssetBundle包的时候,一定要把路径、资源包名称、包的后缀都写正确,否则会找不到资源包而加载出错。

另外,我们在刚才说最好在加载并使用它之前,先把依赖的包加载出来,并把它加了红,这里要多说一句哦。

根据我代码的测试,加载先后顺序并不影响关系的依赖:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LoadAssetsBundlePackage : MonoBehaviour
{

    // Use this for initialization
    void Start()
    {
        //先将prefab资源包加载进内存
        AssetBundle sphereAssetBundle = AssetBundle.LoadFromFile("AssetBundles/sphere.assetsbundle");
        //然后再加载prefab
        GameObject prefab = sphereAssetBundle.LoadAsset<GameObject>("Sphere");
        //实例化出一个实体
        Instantiate(prefab);

        //3秒钟后再加载材质和贴图到内存中
        Invoke("LoadMaterialAssetBundle",3.0f);
    }

    /// <summary>
    /// 加载材质和贴图
    /// </summary>
    void LoadMaterialAssetBundle()
    {
        AssetBundle.LoadFromFile("AssetBundles/material.assetsbundle");
    }
}

动态图如下:

【AssetBundle】七:打包生成的manifest文件也就是说资源加载先后并没有强制性要求,哪怕你是后面加载进来的,只要我们之前存在关系,我就能顺藤摸瓜找到你。

这个过程是没有问题的,但是如果这个材质丢失后续补上的过程被玩家看到,那想必是很不好的游戏体验。所以我们知道了有这么个情况,加载顺序还是按照规范来老老实实加载吧! :oops:

 原创内容,未经许可不得擅自转载文章部分或全部内容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章