Unity3d热更新(二)(资源打包AssetBundle)

创建AssetBundle
1.新建一个cube,将其拉倒Project视图里创建预设。
2.在Assets目录下创建Scenes文件夹,创建场景scene1.unity。
3.新建ExportAssetBundles.cs,保存在Assets/Editor目录下。代码如下:

using UnityEngine; using UnityEditor; using System.Collections; public class ExportAssetBundles : MonoBehaviour { [MenuItem("Build/ExportResource")] static void ExportResource() { // 打开保存面板,获取用户选择的路径 string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "assetbundle"); if (path.Length != 0) { // 选择的要保存的对象 Object[] selection = Selection.GetFiltered(typeof(Object), SelectionMode.DeepAssets); // 打包 BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets, BuildTarget.StandaloneWindows); } } [MenuItem("Build/ExportScene")] static void ExportScene() { // 打开面板,选择用户保存的路径 string path = EditorUtility.SaveFilePanel("Save Resource", "", "New Resource", "unity3d"); if (path.Length != 0) { // 要打包的场景 string[] scenes = {"Assets/Scenes/scene1.unity"}; // 打包 BuildPipeline.BuildPlayer(scenes, path, BuildTarget.StandaloneWindows, BuildOptions.BuildAdditionalStreamedScenes); } } }


4.选中预设,运行ExportResource,弹出保存对话框,命名为cube.assetbundle。
5.运行ExportScene,弹出保存对话框,命名为scene1.unity3d。
小提示
1.AssetBundle的保存后缀名可以是assetbundle或者unity3d。
2.BuildAssetBundle要根据不同的平台单独打包,BuildTarget参数指定平台,如果不指定,默认的webplayer。
加载AssetBundle
下面通过一个示例演示如何加载AssetBundle:
using UnityEngine; using System.Collections; public class Load : MonoBehaviour { private string BundleUrl = "file:///C:/Users/Administrator/Desktop/Res/cube.assetbundle"; private string SceneUrl = "file:///C:/Users/Administrator/Desktop/Res/scene1.unity3d"; void Start() { StartCoroutine(Download()); } IEnumerator Download() { // 下载AssetBundle,加载cube using(WWW www = new WWW(BundleUrl)) { yield return www; AssetBundle bundle = www.assetBundle; Instantiate(bundle.Load("Cube")); bundle.Unload(false); yield return new WaitForSeconds(5); } using(WWW www = new WWW(SceneUrl)) { yield return www; Application.LoadLevel("scene1"); } } }


我们在程序加载的时候必须保证先加载公共对象。否则,只能是在各个对象加载成功后,再通过程序手动添加进来,比较繁琐。在实际项目中,由于是团队开发,对象间的依赖关系通常会比较凌乱,最好在开发周期就定好相关的规范约束,方便管理。
【Unity3d热更新(二)(资源打包AssetBundle)】
AssetBundle依赖关系

如果一个公共对象被多个对象依赖,我们打包的时候,可以有两种选取。一种是比较省事的,就是将这个公共对象打包到每个对象中。这样会有很多弊端:内存被浪费了;加入公共对象改变了,每个依赖对象都得重新打包。AssetBundle提供了依赖关系打包。
//启用交叉引用,用于所有跟随的资源包文件,直到我们调用PopAssetDependencies BuildPipeline.PushAssetDependencies(); var options = BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets; //所有后续资源将共享这一资源包中的内容,由你来确保共享的资源包是否在其他资源载入之前载入 BuildPipeline.BuildAssetBundle( AssetDatabase.LoadMainAssetAtPath("assets/artwork/lerpzuv.tif"), null, "Shared.unity3d", options); //这个文件将共享这些资源,但是后续的资源包将无法继续共享它 BuildPipeline.PushAssetDependencies(); BuildPipeline.BuildAssetBundle( AssetDatabase.LoadMainAssetAtPath("Assets/Artwork/Lerpz.fbx"), null, "Lerpz.unity3d", options); BuildPipeline.PopAssetDependencies(); //这个文件将共享这些资源,但是后续的资源包将无法继续共享它 BuildPipeline.PushAssetDependencies(); BuildPipeline.BuildAssetBundle( AssetDatabase.LoadMainAssetAtPath("Assets/Artwork/explosive guitex.prefab"), null, "explosive.unity3d", options); BuildPipeline.PopAssetDependencies(); BuildPipeline.PopAssetDependencies();

    推荐阅读