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");
        }
    }
}

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

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();  

你可能感兴趣的:(Unity)