AssetBundle打包与加载

官方文档
参照视频

1.AssetBundle打包

1.1设置资源的命名和后缀

命名只支持小写
在这里插入图片描述

1.2创建Editor文件夹,在里面创建编辑器打包AssetBundle的脚本

using UnityEditor;
using System.IO;

public class CreateAssetBundles  {

    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string dir = "AssetBundles";
        if( Directory.Exists(dir)==false)
        {
            Directory.CreateDirectory(dir);
        }
        BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
    }
}

压缩方式:
BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩包下,但加载时间长
BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快
BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是我们可以加载指定资源而不用解压全部
注意:使用LZ4压缩,可以获得可以跟不压缩相媲美的加载速度,而且比不压缩文件要小

1.3选择菜单Assers-》点击Build AssetBundles 进行打包

在这里插入图片描述
得到打包后的文件
在这里插入图片描述

2.AssetBundle加载方式

原则上在使用资源之前需要先加载材质包,再创建prefab,防止材质丢失。share.unity3d为cubewallf的材质贴图包,share.unity3d和cubewall.unity3d加载先后顺序不影响

加载方式1:本地加载 AssetBundle.LoadFromFile

AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/share.unity3d");
 AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/cubewall.unity3d");
 GameObject wallPrefab = ab.LoadAsset<GameObject>("CubeWall");
 Instantiate(wallPrefab);

加载方式2: 内存中加载(异步) AssetBundle.LoadFromMemoryAsync

IEnumerator LoadFromMemoryAsync(string path)
    {
    
    
        AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));
        yield return createRequest;
        AssetBundle bundle = createRequest.assetBundle;
        var prefab = bundle.LoadAsset<GameObject>("MyObject");
        Instantiate(prefab);
    }

内存中加载(同步) AssetBundle.LoadFromMemory

AssetBundle ab=AssetBundle.LoadFromMemory(File.ReadAllBytes(path));

加载方式3:网络加载 UnityWebRequestAssetBundle

IEnumerator InstantiateObject()
{
    
    
    string uri = "file:///" + Application.dataPath + "/AssetBundles/" + assetBundleName; 
    UnityEngine.Networking.UnityWebRequestAssetBundle request 
        = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(uri, 0);
    yield return request.SendWebRequest();
    AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);
    GameObject cube = bundle.LoadAsset<GameObject>("Cube");
    GameObject sprite = bundle.LoadAsset<GameObject>("Sprite");
    Instantiate(cube);
    Instantiate(sprite);
}

(弃用)网络加载2 LoadFromCacheOrDownload(string url, int version);

IEnumerator Start()
    {
    
    
        while (!Caching.ready)
            yield return null;

        using (var www = WWW.LoadFromCacheOrDownload("https://myserver.com/myassetBundle.unity3d", 5))
        {
    
    
            yield return www;
            if (!string.IsNullOrEmpty(www.error))
            {
    
    
                Debug.Log(www.error);
                yield return null;
            }
            var myLoadedAssetBundle = www.assetBundle;

            var asset = myLoadedAssetBundle.mainAsset;
        }
    }

API2:LoadFromCacheOrDownload(string url, int version, uint crc); crc表示校验完整性,crc在.mainifest文件里
在这里插入图片描述

3.通过Manifest文件得到某个包的依赖

AssetBundles.manifest 里面包含所有包对应的依赖
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/44e22eec07d7485fb7acc569b00c1cf2.png
代码:

AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");//固定为AssetBundles
AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");//固定为“AssetBundleManifest”
string[] strs = manifest.GetAllDependencies("cubewall.unity3d");
foreach (string name in strs) {
    
    
    print(name);//share.unity3d
    AssetBundle.LoadFromFile("AssetBundles/"+ name); //加载cubewall.unity3d的依赖包
}

4.AssetBundle的卸载

  • 卸载可以减少内容的使用
  • 不当的卸载,有可能导致丢失(材质丢失bug红等)
  • AssetBundle.Unload(true) 卸载所有资源,即使有资源被使用着,推荐这个方法,卸载前确保依赖的包不被其他物体使用了。可以在切换场景是loading scene阶段去卸载
  • AssetBundle.Unload(false) 卸载所有没有被使用的资源,一般不用这个方法,会导致某些资源不被卸载,导致内存被滥用
  • 个别资源的卸载 1.通过Resources.UnloadUnusedAssets 2.场景切换的时候,自动调用Resources.UnloadUnusedAssets

5.Unity AssetBundle Browser Tool

使用文档
github下载地址
在这里插入图片描述
在这里插入图片描述