AssetBundle(二)——AssetBundle使用流程

一:设置AssetBundle属性

在编辑器预览窗口的右下角有一个AssetBundle的属性设置

第一栏是AB包的属性名字,第二栏是AB包的属性变体(后缀)
——AB包的变体可以不设置(后缀不能为unity,会报空指针)
——AB包的属性和后缀是不区分大小写的
——AB包的名称是可以指定目录路径的(例如:prefab/cube或者prefab\cube)

设置属性需要注意的地方:如果想要将几个资源打包到同一个包中,则资源的路径要相同,变体也要相同。如果名字相同,变体不相同仍会打到不同的包里


二:构建AB包

两种方式:
——通过资源的ab包属性打包(手动设置或者代码设置),之后通过打包函数进行打包 
——传入一个AssetBundleBuild对象的数组(AssetBundleBuild中的assetNames必须是以Assets/开头的路径),之后通过打包函数进行打包 

using UnityEngine;
using UnityEditor;
using System.IO;

public class ABEditor
{
    [MenuItem("AB/Build AB1")]
    private static void BuildAB1()
    {
        string outputPath = Application.dataPath + "/AssetBundles";
        if (!Directory.Exists(outputPath))
        {
            Directory.CreateDirectory(outputPath);
        }
        BuildPipeline.BuildAssetBundles(outputPath, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);

        AssetDatabase.Refresh();
    }

    [MenuItem("AB/Build AB2")]
    private static void BuildAB2()
    {
        string outputPath = Application.dataPath + "/AssetBundles";
        if (!Directory.Exists(outputPath))
        {
            Directory.CreateDirectory(outputPath);
        }

        List<AssetBundleBuild> abBuilds = new List<AssetBundleBuild>();
        foreach (var v in abAssetDict.Values)
        {
            AssetBundleBuild bundle = new AssetBundleBuild
            {
                assetBundleName = v.abName,
                assetNames = new string[] { v.assetPath },
            };
            abBuilds.Add(bundle);
        }
        BuildPipeline.BuildAssetBundles(outputPath, abBuilds.ToArray(), BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
    }
}

BuildAssetBundleOptions:打包选项
1.BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是LZMA只支持顺序读取,使用时需要将整个包进行解压缩,加载时间变得更长,解压后的包会通过LZ4算法重新压缩存储在磁盘上
2.BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快,但是下载速度会慢
3.BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4算法压缩,压缩后的包比LZMA算法压缩的包大,但是加载速度快

打包时注意,例如A和B都使用了同一个材质,将材质单独打成一个AB包,则打包后,A和B的包中就不会包含材质资源而是存了一份材质包的引用路径,减少了AB包的大小
同样的,一个文件夹中有AB两个资源,给A资源设置了AB包属性,B资源没有设置AB包属性,同时给文件夹也设置了AB包属性,则A资源会单独打一个包,B资源会打进文件夹的AB包中,A资源就不会打进文件夹的AB包中


三:上传AB包——使用NetBox2模拟服务器

使用NetBox2可以快速搭建一个本地服务器,它的根目录就是当前NetBox的目录

——运行程序
双击运行之后发现出现了403 Forbidden,这是因为我们没有默认的首页(可以用html写一句话当作主页)

"http://localhost:64283/"就是我们的服务器网址,后面再加上打包的路径就是AB包的服务器地址(http://localhost:64283/AssetBundles/cube)



——上传文件
将打包好的文件夹整个拖入NexBox的根目录下(与NetBox可执行文件同级)


四:加载AB包

——从本地加载资源

using UnityEngine;
using System.Collections;

public class Test : MonoBehaviour
{
    private string path = "/Users/liu/Desktop/testproject/AssetBundles/cube";

    private void Awake()
    {
        LoadAB_Sync();
        //StartCoroutine(LoadAB_Async());
    }

    private void LoadAB_Sync()
    {
        AssetBundle ab = AssetBundle.LoadFromFile(path);
        Instantiate(ab.LoadAsset("cube"));
    }

    private IEnumerator LoadAB_Async()
    {
        AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
        yield return request;
        AssetBundle ab = request.assetBundle;
        Instantiate(ab.LoadAsset("cube"));

    }
}


——从内存加载资源

using UnityEngine;
using System.Collections;
using System.IO;

public class Test : MonoBehaviour
{
    private string path = "/Users/liu/Desktop/testproject/AssetBundles/cube";

    private void Awake()
    {
        LoadAB_Sync();
        //StartCoroutine(LoadAB_Async());
    }

    private void LoadAB_Sync()
    {
        AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));
        Instantiate(ab.LoadAsset("cube"));
    }

    private IEnumerator LoadAB_Async()
    {
        AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));
        yield return request;
        AssetBundle ab = request.assetBundle;
        Instantiate(ab.LoadAsset("cube"));

    }
}


——使用UnityWebRequest加载资源

using UnityEngine;
using System.Collections;
using System.IO;
using UnityEngine.Networking;

public class Test : MonoBehaviour
{
    //本地路径需要加file:///
    private string path = @"file:////Users\liu\Desktop\testproject\AssetBundles\cube";

    private void Awake()
    {
        StartCoroutine(LoadAB_Async());
    }

    private IEnumerator LoadAB_Async()
    {
        UnityWebRequest request = new UnityWebRequest(path);
        yield return request.SendWebRequest();
        AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
        Instantiate(ab.LoadAsset("cube"));
    }
}

五:卸载

——assetbundle.Unload(bool unloadAllLoadedObjects)
如果为true,则会卸载当前包所有资源,包括正在被其他包依赖的资源
如果为false,则会卸载当前包未被依赖的资源,被其他包依赖的资源不会被卸载


——AssetBundle.UnloadAllAssetBundles(bool unloadAllObjects)
如果为true,则会卸载所有AB资源,包括正在被其他包依赖的资源
如果为false,则会卸载未被依赖的AB资源,被其他包依赖的资源不会被卸载


六:注意事项

——Unity加载的AB包,即使游戏中没有对该assetbundle的引用,不主动调用Unload或UnloadAllAssetBundles的话,该AB包是不会被释放掉的,指向该assetbundle的弱引用也不会变为空,可以隔一段时间调用一次Resources.UnloadUnusedAssets
——如果依赖的资源在使用下被卸载了,再次加载出依赖的资源并不会建立起引用,因为卸载之后它们的引用就断开了,就算再次加载出依赖的资源也不会与之前的预制体所连接,除非同时再次加载出预制体和资源

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hello Bug.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值