Unity5的AssetBundle(一、打包)

Unity5的AssetBundle管理(打包)

参考链接:(本文有个人修改,请点击链接查看原文。)

UWA:
4:https://blog.uwa4d.com/archives/ABtopic_1.html
5:https://blog.uwa4d.com/archives/ABtopic_2.html

一、简介

1.API

//public static AssetBundleManifest BuildAssetBundles(存放地址,打包选项,打包平台);

调用BuildPipeline.BuildAssetBundles,引擎将自动根据资源的assetbundleName属性(以下简称abName)批量打包,自动建立Bundle以及资源之间的依赖关系。


2.打包规则

在资源的Inspector界面最下方可设置一个abName,每个abName(包含路径)对应一个Bundle,即abName相同的资源会打在一个Bundle中。如果所依赖的资源设置了不同的abName,则会与之建立依赖关系,避免出现冗余。

支持增量式发布,即在资源内容改变并重新打包时,会自动跳过内容未变的Bundle。因此,相比4.x,会极大地缩短更新Bundle的时间。


3.打包选项

BuildAssetBundleOptions枚举:

5.x下默认开启的三个选项(CompleteAssets ,用于保证资源的完备性;CollectDependencies,用于收集资源的依赖项;DeterministicAssetBundle,用于为资源维护固定ID)之外,5.x中新增了以下选项:

ForceRebuildAssetBundle
用于强制重打所有AssetBundle文件;

IgnoreTypeTreeChanges
用于判断AssetBundle更新时,是否忽略TypeTree的变化;

AppendHashToAssetBundleName
用于将Hash值添加在AssetBundle文件名之后,开启这个选项,可以直接通过文件名来判断哪些Bundle的内容进行了更新(4.x下普遍需要通过比较二进制等方法来判断,但在某些情况下即使内容不变重新打包,Bundle的二进制也会变化)。

与4.x不同的是,对于移动平台,5.x下默认会将TypeTree信息写入AssetBundle,因此在移动平台上DisableWriteTypeTree选项也变得有意义了。

注:压缩格式:打包默认为LZMD压缩格式,具有最高的压缩比;使用UncompressedAssetBundle为不压缩;使用ChunkBasedCompression为LZ4格式压缩,压缩比没有LZMA高,但是加载速度大幅提高,推荐使用。


4.Manifest文件

在4.x版本中,我们通常需要自行维护配置文件,以记录AssetBundle之间的依赖关系,并供运行时使用。而在5.x版本中,Manifest文件可以免去这一过程。

在打包后生成的文件夹中,每个Bundle都会对应一个manifest文件,记录了Bundle的一些信息,但这类manifest只在增量式打包时才用到;

同时,根目录下还会生成一个同名manifest文件及其对应的Bundle文件,通过该Bundle可以在运行时得到一个AssetbundleManifest对象,而所有的Bundle以及各自依赖的Bundle都可以通过该对象提供的接口进行获取。


5.Variant参数

在资源的Inspector界面最下方,除了可以指定abName,在其后方还可以指定Variant。打包时,Variant会作为后缀添加在Bundle名字之后。相同abName,不同variant的Bundle中,资源必须是一一对应的,且他们在Bundle中的ID也是相同的,从而可以起到相互替换的作用。

当需要为手机和平板上的某个UI界面使用两套分辨率不同的纹理、Shader,以及文字提示时,借助Variant的特性,只需创建两个文件夹,分别放置两套不同的资源,且资源名一一对应,然后给两个文件夹设置相同的abName和不同的variant,再给UI界面设置abName,然后进行打包即可。运行时,先选择合适的依赖包加载,那么后续加载UI界面时,会根据已加载的依赖包,呈现出相对应的版本。


6.注意点

abName可通过脚本进行设置和清除,也可以通过构造一个AssetBundleBuild数组来打包。

新机制打包无法指定Assetbundle.mainAsset,因此无法再通过mainAsset来直接获取资源。

开启DisableWriteTypeTree可能造成AssetBundle对Unity版本的兼容问题,但会使Bundle更小,同时也会略微提高加载速度。

Prefab之间不会建立依赖,即如果Prefab-A和Prefab-B引用了同一张纹理,而他们设置了不同的abName,而共享的纹理并未设置abName,那么Prefab-A和Prefab-B可视为分别打包,各自Bundle中都包含共享的纹理。因此在使用UGUI,开启Sprite Packer时,由于Atlas无法标记abName,在设置UI界面Prefab的abName时就需要注意这个问题。

5.x中加入了Shader stripping功能,在打包时,默认情况下会根据当前场景的Lightmap及Fog设置对资源中的Shader进行代码剥离。这意味着,如果在一个空场景下进行打包,则Bundle中的Shader会失去对Lightmap和Fog的支持,从而出现运行时Lightmap和Fog丢失的情况.而通过将Edit->Project Settings->Graphics下shader Stripping中的modes改为Manual,并勾选相应的mode即可避免这一问题。


二、实战

1.代码一键设置abName

public static void MakeABNames()
   {
      var dir = "Assets/Packages/";//需要打包的资源路径
      //清除不需要打包的资源的ab名
//从Project面板找含有""字段的物体,即遍历Project面板所有物体,返回GUID(全局唯一标识符)数组
      {
       var assetPath = AssetDatabase.GUIDToAssetPath(assetGuid);
       //将GUID(全局唯一标识符)转换为对应的资源路径;
      //所有的路径都是相对于工程目录文件。例如” Assets/MyTextures/hello.png”
       var assetImport = AssetImporter.GetAtPath(assetPath);
       var bundleName = assetImport.assetBundleName;
       if (string.IsNullOrEmpty(bundleName))
              continue;
       if (!assetPath.StartsWith(dir)) //Packages目录之外的资源不打包,去除AB名
            assetImport.assetBundleName = null;
       }

       //设置要打包的资源的ab名
       foreach(var filepath in Directory.GetFiles(dir,"*.*",SearchOption.AllDirectories))
          {
             if (filepath.EndsWith(".meta")) continue;
             var importer = AssetImporter.GetAtPath(filepath);
             if(importer==null)
                 continue;
             var bundleName = filepath.Substring(dir.Length,filepath.Length-dir.Length);
                importer.assetBundleName = bundleName + ".assetBundle";
            }

这样会给目标文件夹中每个资源设置好abName。

2.打包

注意:
1/ Windows系统只能打Windows和Android资源,IOS要在Mac上打。
2/ 打对应平台资源时,必须切换到对应平台:

或者代码切换:

public static bool SwitchActiveBuildTarget(BuildTargetGroup targetGroup, BuildTarget target); //版本不同参数列表可能不同

调用则会尝试切换到平台,切换成功返回True,所以在if()里判断,成功则打包。
这个类还有个常用属性:

 EditorUserBuildSettings.activeBuildTarget; //当前激活的平台

然后调用BuildPipeline.BuildAssetBundle打包:

//使用LZ4压缩格式进行打包
BuildPipeline.BuildAssetBundles(outputPath,
BuildAssetBundleOptions.ChunkBasedCompression,BuildTarget targetPlat);
AssetDatabase.Refresh();//打好资源刷新面板

而一键打包,则要自动切换打包,打包完成切换另一平台打包:
先封装打包目标平台全部资源的方法:BuildAllAssetBundlesToSelectedPlatform
(),然后:

 public static void BuildAllAssetBundlesToAllPlatforms()
        {
            var platforms = new List<BuildTarget>()
            {           
                BuildTarget.Android,
                BuildTarget.StandaloneWindows,
                //windows系统不能打ios资源
                //BuildTarget.iOS,
                // BuildTarget.StandaloneOSXIntel,
            };

            // 打包列出的所有平台
            var currentBuildTarget = EditorUserBuildSettings.activeBuildTarget;
            platforms.Remove(currentBuildTarget);
            //打包当前平台资源
            BuildAllAssetBundlesToSelectedPlatform(currentBuildTarget);

            //切换其他平台,打包其他平台资源
            foreach (var platform in platforms)
            {
                if (EditorUserBuildSettings.SwitchActiveBuildTarget(platform))
                    BuildAllAssetBundlesToSelectedPlatform(platform);
                else
                    Debug.LogError("Cannot switch platform to:" + GetPlatformName(platform));
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值