Unity5 AssetBundle的一些整理(一)

最近整理一些AssetBundle的知识,包括AB的打包(差异包),读取等。是一个比较大的功能点,在这记录一下,以免后面自己也乱了。要是有什么错误的地方欢迎各位看客指出。第一篇的话就说说AB最基础的实现。


首先当然是什么是AssetBundle,网上有很多的详细介绍,我个人的理解就是,AssetBundle指把Asset资源例如,Texture图片,Prefab预设,Animation动画这些打包成一个个的Bundle。然后在代码中就可以根据路径获取到这些Bundle,解析出里面的Asset用于使用。

代码中读取工程中的资源,还有一种方法是Resources.Load()读取Asset/Resources文件夹下面的资源。或者是Editor环境下的UnityEditor.AssetDatabase.LoadAssetAtPath()。至于为什么要这么麻烦的将资源打包成AB文件再去动态读取,最主要的目的就是为了可以热更新资源。

举个例子:当你的游戏上线了,有一天你觉得你的登录界面的按钮不好看,想替换下登录界面的样式。这时你可能需要在自己的项目工程中替换好样式然后出一个新的apk或app包,然后去走包体更新的流程。这样明显十分的麻烦,想想苹果爸爸的审核流程就望而却步。AB就可以解决上面的这个问题,首先在游戏上线前,先将你的登录界面打包成LoginAB资源,然后使用代码读取这个AB资源里面的UI显示在界面上。当你需要更新界面的时候,你只要把修改后的界面打成一个新的LoginAB,放到你的服务器上,游戏启动的时候在服务器下载新的LoginAB放入手机的可读取目录中(例如IOS的Documents下),当要显示登录界面的时候,先判断手机的可读取目录中是否有新的LoginAB,有的话则读取该AB,不然读取包体内原本的LoginAB。这样进入游戏你的登录界面就是最新的界面了(当然启动游戏下载服务器上的AB和读取下载下来的AB这块的逻辑需要预先写好哈)。

大致了解了AB的作用后,那么接下来要做的就是如何用代码实现上面的这些功能,资源的打包,读取,下载,热更新等等。


下面列一些需要的知识点:

(1)unity5.0之后所有的资源都多了一个新的属性AssetBundle,里面可以填写assetBundleName和assetBundleVariant。如下图所示:

Unity5 AssetBundle的一些整理(一)_第1张图片

assetBundleName:当你给一个Asset添加assetBundleName时,即等于告诉unity这些资源是需要打包成AB的。AB的名称就是你这里设置的名称,多个不同的Asset添加同一个name的的话,这些Asset会被打进同一个AB中。需要注意的是name中字母需要全部使用小写,文件名后缀可以自定义。并且可以使用'/'符号来进行分层。例如A.prefab的assetBundleName为b/c/a.ab,那么打出来的AB则会在指定父目录即StreamingAssets的b文件夹里的c文件夹下,名为a.ab。

assetBundleVariant:资源标签(本文中暂时没用到),在打包时,会作为后缀添加在assetbundleName之后,通常用作LOD。一个资源只可以设置个标签。例如有两套贴图资源,一套高清,一套普通,然后给他们设置同样的assetBundleName为MyAsset,高清资源的assetBundleVariant 设置为LD,普通资源设置为SD,那么就可以根据不同设备通过选择加载MyAsset.LD或MyAsset.SD来切换资源库,这样依赖MyAsset的Prefab就可以动态切换版本了。注意,两套资源集的asset必须完全一一对应,对于unity来说LD和SD是同一个bundld,同一时刻只能加载其中一个。

对应的结构体:

namespace UnityEditor {
    //
    // 摘要:
    //     AssetBundle building map entry.
    public struct AssetBundleBuild {
        //
        // 摘要:
        //     AssetBundle name.
        public string assetBundleName;
        //
        // 摘要:
        //     AssetBundle variant.
        public string assetBundleVariant;
        //
        // 摘要:
        //     Asset names which belong to the given AssetBundle.
        public string[] assetNames;
        //
        // 摘要:
        //     Addressable name used to load an asset.
        public string[] addressableNames;
    }
}

(2)打包的相关脚本:

当设置好上述属性时,如何将它打成我们想要的AB包呢,接下来就要使用代码实现。在Assets/Editor目录下新建一个脚本,如下:

using UnityEngine;
using UnityEditor;

namespace Tool.AssetBundle {

	public class BuildAssetBundle : MonoBehaviour {

        // 打包输出目录,通常为StreamingAssets(若不存在该目录需要新建一个),这是Unity的一个特殊目录,打包时该目录下所有资源会被打进包体中
        //StreamingAssets与Resources的区别在于,StreamingAssets不会被压缩打进包体,而Resources会被压缩
        public static readonly string RES_OUTPUT_PATH = "Assets/StreamingAssets";

        //MenuItem会在unity菜单栏添加自定义新项
        [MenuItem("CustomEditor/Build AssetBundle")]
        private static void Build() {
            //打包,第一个参数是AB的输出目录,第二个参数是打包选项,第三个参数是打包的平台,IOS,Android,Win要区分开,不然AB使用的时候会有问题。
            BuildPipeline.BuildAssetBundles(RES_OUTPUT_PATH, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64);
        }
    }
}
上面的这就是一段最简单的AB打包代码,然后返回Unity界面,在菜单栏选择CustomEditor下面的Build AssetBundle,如图:
Unity5 AssetBundle的一些整理(一)_第2张图片
Unity5 AssetBundle的一些整理(一)_第3张图片
就会发现在StreamingAssets下多了一个prefabs文件夹里面有一个canvas.ab就是打包成的AB资源了。

你会发现除了canvas.ab还多了很多其他的文件,这些留到下一篇再解释,包括代码中一些需要注意的地方。

你可能感兴趣的:(AssetBundle)