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