Unity中AssetBundle的打包和加载工具

转载自: https://blog.csdn.net/beihuanlihe130/article/details/76216072?from=timeline


在Unity中,实现物体动态加载的方法主要包括了Resources.Load()和AssetBundle两种。当我们的游戏资源需要热更新时,AssetBundle是一种不错的实现方式。 Unity官方提供了十分方便的打包工具 Asset Bundle Browser,同时该工具也作为开源项目放到了 GitHub上。通过Window->AssetBundle Browser便可打开该工具进行相关操作。我们只需将需要打包的内容拖拽到工具中便会生成相应的Bundle。如果我们同时打多个Bundle,如果Bundle中出现了重复的资源,该工具也会在旁边以黄色的小叹号给我们提示,这样我们便可以将重复的资源单独打包,从而让我们的Bundle运行更高效。
在命名Bundle的过程中,如果我们不手动添加.assetbundle后缀的话,打包出来的文件也不存在该后缀,当我们为AssetBundle添加后缀后打包出来的bundle文件也会自动包含该后缀名称(该后缀名称主要取决于我们的文件服务器可以下载的文件类型,只有可以下载的文件才能通过Unity的WWW方法加载出来,否则将会报错。如果要修改文件服务器中的下载类型,只需修改服务器中的配置文件web.config文件中的MIME属性便可。)
<configuration>
    <system.webServer>
        <staticContent>
            <mimeMap fileExtension="." mimeType="application/File" />
            <mimeMap fileExtension=".assetbundle" mimeType="unity3d/assetbundle" />
         </staticContent>
    </system.webServer>
</configuration>
  
  

    如上所示,fileExtension=”.”表示可以下载无后缀的文件,当我们设置fileExtention=”.assetbundle”时,则表示可以下载后缀名为.assetbundle的文件。

    我们打包的assetbundle文件,除了.assetbundle文件外,还包含了manifest文件。同时除了我们已经命名的文件外,还包含了一个则外的assetbundle文件和manifest文件,这两个文件中包含了我们此次打包的所有资源信息。其中Manifest文件信息如下所示:

    ManifestFileVersion: 0
    CRC: 3392523828
    AssetBundleManifest:
      AssetBundleInfos:
        Info_0:
          Name: overlookpointparent.assetbundle
          Dependencies: {}
        Info_1:
          Name: dotweenpathparent.assetbundle
          Dependencies: {}
        Info_2:
          Name: props.assetbundle
          Dependencies: {}
      
      

      Manifest文件中包含了我们打包的Bundle中的信息。我们在加载Bundle时一般不会加载Manifest文件,我们可以通过包含所有Bundle信息的文件来动态获取每一个Bundle的信息。

      在Unity中,加载Bundle的方式主要通过WWW来实现

      WWW www = new WWW(URL);
      WWW www = WWW.LoadFromCacheOrDownload(URL,hash);
        
        
      • 1
      • 2

      上述方法中,第一种在每次执行时都会从给定地址中获取相应的文件并加载,如果是在服务器的文件,则需要用户每次都进行下载,用户体验不会很好,第二种方式则会先对缓存目录进行判断,如果当前缓存的Bundle与给定地址的Bundle版本一致,则直接加载缓存中的文件,根据Hash值判断如果不一致,则需要重新下载之后再加载。

      那么我们如何获取每一个Bundle的Hash值呢,这就用到了我们上边提到的Manifest文件。在Manifest文件中保存了所有Bundle的Hash值。

      我们不能直接加载Manifest文件来获取,需要通过那个包含所有Bundle信息的Bundle文件来获取Manifest信息。我们可以每次都通过new WWW(URL)来下载占用较小空间但包含全部Bundle信息的文件来获取Hash值,通过判断Hash值来动态加载其他占用空间较大的Bundle。

      IEnumerator DownloadManifestFile(string fullBundlePath)
      {
          WWW ManifestBundleFromWWW = new WWW(fullBundlePath);
          yield return ManifestBundleFromWWW;
          if (string.IsNullOrEmpty(ManifestBundleFromWWW.error))
          {
              AssetBundle bundle = ManifestBundleFromWWW.assetBundle;
              AssetBundleManifest[] abms = bundle.LoadAllAssets<AssetBundleManifest>();
              if (abms.Length == 1)
              {
                  string[] allAssetBundleNames = abms[0].GetAllAssetBundles();
                  Hash128[] allAssetBundleHashes = new Hash128[allAssetBundleNames.Length];
                  for (int i = 0; i < allAssetBundleNames.Length; i++)
                      allAssetBundleHashes[i] = abms[0].GetAssetBundleHash(allAssetBundleNames[i]);
              }
                  bundle.Unload(false);
          }
          else
              Debug.Log(ManifestBundleFromWWW.error);
          yield return null;
      }
        
        
        <

      根据以上我们得到的AssetBundle的Name和Hash值,再加上前边服务器的地址,我们便可以得到每一个Bundle的地址以及每一个Bundle的Hash值,通过WWW.LoadFromCacheOrDownload(url,hash)便可动态加载所有的Bundle,只有Bundle发生变化时才会从指定地址重新下载。

      在加载AssetBundle时,根据AssetBundle的名字进行加载。

          string detailBundlePath = "(BundleAddress)/(BundleName)";//BundleName为上边的allAssetBundleNames[N]
          WWW www = new WWW(detailBundlePath);//WWW.LoadFromCacheOrDownload(detailBundlePath, hash);//这一行可以通过Hash值来判断是否需要下载。
          yield return allAssetBundleFromWWW[bundleIndex];
          AssetBundle bundle = www.assetBundle;
          GameObject[] allObjs = bundle.LoadAllAssets<GameObject>();//可以根据不同的类型加载不同的AssetBundle。
        
        

        值得注意的是,在WebGL中,本人测试版本为5.6.2f,使用WWW.LoadFromCacheOrDownload()方法进行下载时,会出现浏览器占用大量内存的情况,暂时还没有找到合适的解决方法,只能通过new WWW(url)来暂时实现需要的功能。要使用WWW.LoadFromCacheOrDownload()方法在WebGL中还需要深入的研究。

        猜你喜欢

        转载自blog.csdn.net/cui6864520fei000/article/details/85890077