AssetBundle的基础使用

一、关于AssetBundle

1.什么是AssetBundle

1) AssetBundle是一种经过Unity引擎处理了的资源包

2) 已经序列化的资源

3) 具有针对平台的特性

4) 外部不相干,使用同样加密方式的包,可以互相调用

2.类型

1) 一个场景打成一个AB包,使用的时候,是将场景加载到游戏中

2) 松散资源包,一堆可复用的资源打成一个包,使用的时候,是按需载入包

3.作用

1) 最小化APP安装包

1) 增量更新

3) 更好的控制实时的内存消耗

4) 选择性的提供不同的内容

5) 减少打包和迭代时间

二、打包AssetBundle

打包方法:  BuildPipeline.BuildAssetBundles()

我们看到BuildAssetBundles() unity提供了两种重载方法,先来说第一种

public static AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);

这里有三个参数,第一个是输出路径,第二个打包的配置选项(一般选压缩格式),第三个是打包的目标平台

注:assetbundle的压缩格式有3中:

1)LZMA --> BuildAssetBundleOptions.None    包最小,加载最慢

2)LZ4 --> BuildAssetBundleOptions.ChunkBasedCompression    包比不压缩小,加载比不压缩略慢

1)不压缩 --> BuildAssetBundleOptions.UncompressedAssetBundle    包最大,加载最快

这种方法主要是根据我们在Inspector面板中对物体设置的assetbundle名进行打包,比如

扩展编辑器的打包代码,Directory.CreateDirectory(savePath); 把文件保存在asset的同级目录。

using UnityEditor;
using System.IO;

public class BuildAssetBundle : Editor
{
    private static string savePath = "AssetBundles";

    [MenuItem("Tools/BuildAssetBundle")]
    public static void BuildAssetBunlde()
    {
        if (Directory.Exists(savePath) == false)
        {
            Directory.CreateDirectory(savePath);
        }
        BuildPipeline.BuildAssetBundles(savePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
        AssetDatabase.Refresh();
    }
}

还有根据路径打包

public static AssetBundleManifest BuildAssetBundles(string outputPath, AssetBundleBuild[] builds, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);

这个方法多了一个参数AssetBundleBuild[] builds

我们可以看到是Unity封装的一个打包结构体

必须设置assetBundleName和assetNames,其它可设可不设

assetBundleName即为打出的assetbundle名

assetNames为你要打包的资源路径,这里使用相对路径,它是一个数组,说明可以把多个对象打成一个assetbundle。

第二种打包方法代码

 

        if (Directory.Exists(savePath) == false)
        {
            Directory.CreateDirectory(savePath);
        }

        List<AssetBundleBuild> builds = new List<AssetBundleBuild>();
        
        AssetBundleBuild build = new AssetBundleBuild();
        build.assetBundleName = "Micro_Wizard.unity3d";
        build.assetNames = new string[] { "Assets/Toon/Micro_Wizard.prefab" };
        builds.Add(build);

        BuildPipeline.BuildAssetBundles(savePath, builds.ToArray(), BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
        AssetDatabase.Refresh();

三、加载AssetBundle

1.从本地文件中加载

    public void LoadFromFile()
    {
        AssetBundle assetBundle = AssetBundle.LoadFromFile(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d");
        Instantiate(assetBundle.LoadAsset<GameObject>("Micro_Wizard.prefab"));
    }

2.从内存中加载

    public void LoadFromMemory()
    {
        AssetBundle assetBundle = AssetBundle.LoadFromMemory(File.ReadAllBytes(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d"));
        Instantiate(assetBundle.LoadAsset<GameObject>("Micro_Wizard.prefab"));
    }

3.从文件流加载

    public void LoadFromStream()
    {
        var fileStream = new FileStream(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d", FileMode.Open, FileAccess.Read);
        AssetBundle assetBundle = AssetBundle.LoadFromStream(fileStream);
        Instantiate(assetBundle.LoadAsset<GameObject>("Micro_Wizard.prefab"));
    }

4.UnityWebRequest加载

    public void WebRequest()
    {
        StartCoroutine(WaitWebRequest());
    }

    IEnumerator WaitWebRequest()
    {
        UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d");   
        yield return request.SendWebRequest();
        //AssetBundle assetBundle = DownloadHandlerAssetBundle.GetContent(request);
        AssetBundle assetBundle = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
        Instantiate(assetBundle.LoadAsset<GameObject>("Micro_Wizard.prefab"));
    }

5.WWW加载

注:从2018版本后,这个方法已过时,使用UnityWebRequest方法代替

    public void WWWLoad()
    {
        StartCoroutine(WaitWWWLoad());
    }

    IEnumerator WaitWWWLoad()
    {
        while (Caching.ready == false)
            yield return null;

        WWW www = WWW.LoadFromCacheOrDownload(Application.dataPath + "/../AssetBundles/Micro_Wizard.unity3d", 1);
        yield return www;

        if (!string.IsNullOrEmpty(www.error))
        {
            Debug.Log(www.error);
            yield break;
        }
        AssetBundle assetBundle = www.assetBundle;
        Instantiate(assetBundle.LoadAsset<GameObject>("Micro_Wizard.prefab"));
    }

三、卸载AssetBundle

方法1:AssetBundle.Unload(true)、AssetBundle.Unload(false)

常用于资源引用为0时调用

参数为true时,所有在当前场景中使用的引用物体都会被销毁,所有有引用的话,也会丢失。

参数为false时,assetbundle会被释放,而从中实例化出来的物体,会切断与原assetbundle的引用关系。(所以在使用这种情况下,当再次加载时即会产生资源冗余)

在实际使用中无论参数时true还是false似乎都不能很好的满足我们的需求,所以这里我们可以设计一个引用计数法来处理。

1.记录引用次数:

            1)有某个包依赖,次数+1

            2)有某个内容被实例化创建出来,次数+1

            3)依赖包卸载,次数-1

            4)实例化出来的物体被回收,次数-1

2.使用计次:当引用次数为0时,且一段时间没有再被引用时就可以使用AssetBundle.Unload(false)进行安全卸载。

方法2:Resources.UnloadUnusedAssets()

作用如名所诉卸载没有被调用的资源,这时一个异步方法,但也挺消耗性能。

常用于关卡切换,场景切换时调用。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值