欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Unity学习之AssetBundle基础和构建使用讲解

程序员文章站 2022-06-29 08:18:05
assetbundle是什么 assetbundle是unity引擎提供的一种资源管理技术,可以用来动态的加载卸载资源,减少运行时内存压力,所以也是一种热更新技术。它是一种特定的...

assetbundle是什么

assetbundle是unity引擎提供的一种资源管理技术,可以用来动态的加载卸载资源,减少运行时内存压力,所以也是一种热更新技术。它是一种特定的压缩包,它可以包含模型,材质,预设包,音频,甚至整个场景。

构建assetbundle

创建一个名为editor的文件夹,新建一个c#脚本buildassetbundle

using unityengine;
using unityeditor;
using system.io;

public class buildassetbundle {

    [menuitem("assetbundletools/buildallassetbundles")]
    public static void buildallassetbundle()
    {
        string outpath = string.empty;
        outpath = application.streamingassetspath;
        if(!directory.exists(outpath))
        {
            directory.createdirectory(outpath);
        }
        buildpipeline.buildassetbundles(outpath, buildassetbundleoptions.none, buildtarget.standalonewindows64);
    }
}

该脚本会创建一个名为“assetbundletools”的菜单项,点击里面的“buildallassetbundles”会执行这段代码。

这里会自动创建一个streamingassets文件夹,这是我们要打包的输出路径,streamingassets是一个特殊文件夹,放在这里的资源在打包成apk或ipa是不会被压缩的,当然你也可以打包进assetbundles文件夹。

assetbundle的压缩方式:

在这之前先说一下lzma和lz4这两种压缩方式:

lzma压缩方式会让文件大小尽可能的小,但是在使用之前需要对整个包解压缩,解压缩的过程可能会导致稍长的加载时间。

lz4压缩方式会比lzma压缩的文件大,但是在使用时不需要对整个包进行解压,它是基于“块”的压缩算法,可对单个块解压,速度会更快。

buildpipeline.buildassetbundles这个是打包资源的关键方法,里面有3个参数:

- 第一个是打包的输出路径

- 第二个buildassetbundleoptions是打包的设置参数,有3种方式

buildassetbundleoptions.none:使用lzma格式压缩。在使用这种包时会先解压缩,然后使用lz4格式在磁盘上重新压缩。一般适用于需要从网络上下载的小文件。

buildassetbundleoptions.uncompressedassetbundle:不压缩,缺点是文件大,但是加载快。

buildassetbundleoptions.chunkbasedcompression:使用lz4方式压缩。

- 第三个参数是目标平台,这里使用windows64

在unity里标记需要打包的资源

Unity学习之AssetBundle基础和构建使用讲解

在运行脚本时会将所有标记了assetbundle名称的资源打包进目标文件夹中。

打包完成后在目标文件夹里会生成的文件,这里我只打包了一个perfab,会生成这4个文件喎?https: www.2cto.com/kf/ware/vc/"="" target="_blank" class="keylink">vcd4ncjxwpjxpbwcgywx0pq=="这里写图片描述" src="https://www.2cto.com/uploadfile/collfiles/20180531/20180531091624132.png" title="\" />

输出到这个目标文件夹的所有资源都会有一个与之名称想对应的.manifest文件,包括这个目标文件夹本身,所以会有streamingassets和streamingassets.manifest这两个文件。perfab1就是上面我们自己标记的打包资源,同样也对应了一个perfab1.manifest文件。

现在资源有了,我们需要动态加载它。

加载assetbundle

unity中提供了4中方式来加载assetbundle:

1. assetbundle.loadfrommemoryasync

从内存异步加载assetbundle

public class example : monobehaviour
{
    ienumerator loadfrommemoryasync(string path)
    {
        assetbundlecreaterequest createrequest = assetbundle.loadfrommemoryasync(file.readallbytes(path));
        yield return createrequest;
        assetbundle bundle = createrequest.assetbundle;
        var prefab = bundle.loadasset("myobject");
        instantiate(prefab);
    }
}

2.assetbundle.loadfromfile

从本地加载,速度最快。

如果是未压缩或者lz4压缩的,从本地直接读取。

如果是lzma压缩的,先解压缩包,然后加载到内存中。

public class loadfromfileexample extends monobehaviour {
    function start() {
        var myloadedassetbundle = assetbundle.loadfromfile(path.combine(application.streamingassetspath, "myassetbundle"));
        if (myloadedassetbundle == null) {
            debug.log("failed to load assetbundle!");
            return;
        }
        var prefab = myloadedassetbundle.loadasset.("myobject");
        instantiate(prefab);
    }
}

3.www.loadfromcacheordownload

从本地或远程服务器加载,unity官方文档里已经标记为即将被弃用,建议使用unitywebrequest

4.unitywebrequest的downloadhandlerassetbundle(unity 5.3 or newer)

ienumerator instantiateobject()
    {
        string uri = "file:///" + application.datapath + "/assetbundles/" + assetbundlename;
        unitywebrequest request = unitywebrequestassetbundle.getassetbundle(uri);
        yield return request.sendwebrequest();
        assetbundle bundle = downloadhandlerassetbundle.getcontent(request);
        gameobject cube = bundle.loadasset("cube");
        gameobject sprite = bundle.loadasset("sprite");
        instantiate(cube);
        instantiate(sprite);
    }

资源卸载

assetbundle.unload(true)

只释放assetbundle压缩包本身

assetbundle.unload(false)

释放压缩包以及从压缩包里加载(loadasset)出来的资源

resources.unloadunusedassets()

释放没有引用的资源

resources.unloadasset(obj)

释放指定资源

assetbundle依赖关系

在unity5之后的版本只自动处理依赖关系,打包时会把依赖关系存储在manifest清单文件里,我们也可以通过加载manifest来动态获取依赖关系。

加载方式跟加载assetbundle包一样:

assetbundle assetbundle = assetbundle.loadfromfile(manifestfilepath);
assetbundlemanifest manifest = assetbundle.loadasset("assetbundlemanifest");
string[] dependencies = manifest.getalldependencies("assetbundle");
foreach(string dependency in dependencies)
{
    assetbundle.loadfromfile(path.combine(assetbundlepath, dependency));
}

可以直接通过getalldependencies方法获取到一个名为“assetbundle”的包的所有依赖项,然后加载它的依赖项。

喎?https:>