Unity 资源管理 AssetBundle

来源:互联网 发布:高松好玩吗 知乎 编辑:程序博客网 时间:2024/05/18 13:25

Unity 中 AssetBundle 接口和 Resources 接口是对等的。AssetBundle 是把资源打成一个资源包的形式。可以把一个资源打成一个压缩包,也可以把多个资源打成一个压缩包,也可以把一个资源打到多个压缩包中。
在运行的时候,需要先把这个资源包加载进来,然后把资源包中的资源解压出来,然后加载,得到这个资源。在大部分游戏中都是使用这种方式。
这种方式对内存的管理更加直接,因为需要自己管理资源的加载和卸载。更主要的一点是它可以用来做资源的更新,在 Android 和 IOS 下的Resources 文件夹是只读的,不能反复覆盖。它也有一个缺点,就是加载效率较差。
创建一个 AssetBundle 包,打包操作,通常都是在编辑器模式下操作的,所以一般把它做成一个菜单。新建一个脚本Build:

using UnityEngine;using UnityEditor;using System.Collections;public class Build {    //创建一个菜单项    [MenuItem("Publish/Build Bundle")]    public static void BuildBundle ()    {    }}

等Unity编译完后,就会在菜单栏看见 Publish/Build Bundle 菜单,当点击 Build Bundle 时,就会执行我们写好的方法。
这里写图片描述

using UnityEngine;using UnityEditor;using System.Collections;using System.Collections.Generic;public class Build {    //创建一个菜单项    [MenuItem("Publish/Build Bundle")]    public static void BuildBundle ()    {        //定义一个序列来存放将要打包的资源        List<AssetBundleBuild> builds = new List<AssetBundleBuild>();        //实例化一个将要打包的资源        AssetBundleBuild b = new AssetBundleBuild();        //打包后的包名        b.assetBundleName = "test";        //将要打包的资源名称,如果只有一个,就只写一个        //路径请填写自己的        b.assetNames = new string[] { "Assets/Assetbundle/Cube.prefab", "Assets/Assetbundle/Sphere.prefab" };        //把要打包的资源添加到序列        builds.Add(b);        //打包,第一个参数是要打包到哪个路径,这个路径需要存在        //第二个是准备要打包的资源        BuildPipeline.BuildAssetBundles("I:/Build", builds.ToArray());    }}

现在运行游戏,点击菜单栏的按钮,就能在自己定义好的路径下看见打包后的资源
这里写图片描述
test就是我们刚才打包的资源。

既然有打包资源肯定就会有加载资源。加载分为两大步:
1、使用 www 接口加载asset bundle包
2、使用 assetbundle 接口加载包中的资源。
新建一个脚本 Load 给摄像机添加此脚本:

using UnityEngine;using System.Collections;public class Load : MonoBehaviour {    // Update is called once per frame    void Update () {        if (Input.GetKeyDown(KeyCode.J))        {            StartCoroutine(Loads());        }    }    //加载时一个异步的过程,需要使用协程    IEnumerator Loads()    {        //如果从网络加载包,使用 http://xxx....        //如果加载本地 file://c//xxx....        WWW www = new WWW("file://I:/Build/test");        //等待加载包完成        yield return www;        //获取到加载的这个资源        AssetBundle bundle = www.assetBundle;        //异步加载包中的资源        AssetBundleRequest request = bundle.LoadAssetAsync<GameObject>("Assets/Assetbundle/Cube.prefab");        //加载完成        yield return request;        //得到这个gameobject        GameObject go = request.asset as GameObject;        //实例化        Instantiate(go, Vector3.zero, Quaternion.identity);        //释放www        www.Dispose();    }}

这样,就算把 Asset目录下的打包的源文件删除了,也能从打好的包中加载出资源。
这里写图片描述

其实也可以使用

bundle.LoadAsset<GameObject>("Assets/Assetbundle/Cube.prefab");

同步加载,这种加载速度快一些,但是,这有可能会卡住主线程。这取决于项目需求。

工程地址:http://pan.baidu.com/s/1jIpS3zS 密码 5srf

0 0
原创粉丝点击