unity打包-1.Asset Bundle资源打包
Posted mr.chenyuelin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了unity打包-1.Asset Bundle资源打包相关的知识,希望对你有一定的参考价值。
转自:点这里
上面这篇讲得比较详细,先去看看
目录
创建CreateAssetBundles的脚本,加上如下代码,我的会报错
#if UNITY_EDITOR
#endif
采用自定义路径创建ab包
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using UnityEngine;
public class CreateAssetBundles
{
#if UNITY_EDITOR
[MenuItem("AssetBundle/Build WindowAssetBundles")]
public static void BuildAllAssetBundles()
{
string dir = "AssetBundles";
//下面这个是在Assets目录下创建一个streamingAsset文件夹
//string outPath = Application.streamingAssetsPath;
if (Directory.Exists(dir) == false)
{
//在项目下也就是与Assets同级别下创建一个文件夹
Directory.CreateDirectory(dir);
}
List<AssetBundleBuild> builds = new List<AssetBundleBuild>();
AssetBundleBuild build = new AssetBundleBuild();
build.assetBundleName = "ui";
build.assetBundleVariant = "unity3d";
//这里一般从配置文件中读取
build.assetNames = new string[] {
"Assets/prefab/Image3.prefab",
"Assets/ArtRes/pic/number1.png" };
builds.Add(build);
AssetBundleBuild build2 = new AssetBundleBuild();
build2.assetBundleName = "ui2";
build2.assetBundleVariant = "unity3d";
//这里一般从配置文件中读取
build2.assetNames = new string[] {
"Assets/prefab/Image4.prefab",
"Assets/ArtRes/pic/number2.png" };
builds.Add(build2);
//依赖部分打包
AssetBundleBuild publicbuild = new AssetBundleBuild();
publicbuild.assetBundleName = "public";
publicbuild.assetBundleVariant = "unity3d";
//这里一般从配置文件中读取
publicbuild.assetNames = new string[] {
"Assets/Resources/Sprite/weapon4.jpg",
"Assets/Resources/Sprite/weapon3.jpg" };
builds.Add(publicbuild);
//因为我们的场景不能资源放在同一个assetbundle里,所以在新建一个
AssetBundleBuild scenebuild = new AssetBundleBuild();
scenebuild.assetBundleName = "scene";
scenebuild.assetBundleVariant = "unity3d";
//这里一般从配置文件中读取
scenebuild.assetNames = new string[] {
"Assets/minimap.unity" };
builds.Add(scenebuild);
//BuildTarget 选择build出来的AB包要使用的平台
//BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
//自定义路径打包
BuildPipeline.BuildAssetBundles(dir, builds.ToArray(), BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
}
#endif
}
BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是加载时间更长。使用之前需要整体解压。一旦被解压,这个包会使用LZ4重新压缩。使用资源的时候不需要整体解压。在下载的时候可以使用LZMA算法,一旦它被下载了之后,它会使用LZ4算法保存到本地上。
BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快
BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是我们可以加载指定资源而不用解压全部。
注意使用LZ4压缩,可以获得可以跟不压缩想媲美的加载速度,而且比不压缩文件要小。
AssetBundle分组策略
1,把经常更新的资源放在一个单独的包里面,跟不经常更新的包分离
2,把需要同时加载的资源放在一个包里面
3,可以把其他包共享的资源放在一个单独的包里面
4,把一些需要同时加载的小资源打包成一个包
5,如果对于一个同一个资源有两个版本,可以考虑通过后缀来区分 v1 v2 v3 unity3dv1 unity3dv2
1,逻辑实体分组
a,一个UI界面或者所有UI界面一个包(这个界面里面的贴图和布局信息一个包)
b,一个角色或者所有角色一个包(这个角色里面的模型和动画一个包)
c,所有的场景所共享的部分一个包(包括贴图和模型)
2,按照类型分组
所有声音资源打成一个包,所有shader打成一个包,所有模型打成一个包,所有材质打成一个包
3,按照使用分组
把在某一时间内使用的所有资源打成一个包。可以按照关卡分,一个关卡所需要的所有资源包括角色、贴图、声音等打成一个包。也可以按照场景分,一个场景所需要的资源一个包
加载ab包
void Start()
{
//1.同步加载,从本地加载
AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/ui.unity3d");
//异步加载
AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync("AssetBundles/ui.unity3d");
AssetBundle abAsync = request.assetBundle;
//2.从服务器上加载
string url = @"http://localhost/AssetBundles\\ui.unity3d";
UnityWebRequest webRequest = UnityWebRequest.Get(url);
AssetBundle abweb = DownloadHandlerAssetBundle.GetContent(webRequest);
if(ab!=null)
{
//储存时的预制体名字
GameObject image = ab.LoadAsset<GameObject>("Image");
Instantiate(image, transform);
//加载该图片下的子物体
Sprite[] sprites = ab.LoadAssetWithSubAssets<Sprite>("number1");
//for(int i=0;i<sprites.Length;i++)
//{
// Debug.Log(sprites[i].name);
//}
Object[] objects = ab.LoadAllAssets();
for (int i = 0; i < objects.Length; i++)
{
Debug.Log(objects[i].name);
}
}
}
加载依赖
void Start()
{
AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/ui.unity3d");
//同时要加载依赖的assetbundle,
//AssetBundle depend1 = AssetBundle.LoadFromFile("AssetBundles/public.unity3d");
//当该ab包依赖较多时
AssetBundle depend1 = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");//与当前文件夹同名的ab包
AssetBundleManifest manifest = depend1.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//获取该ab包的所有依赖
string[] dependes = manifest.GetAllDependencies("ui.unity3d");
for (int i = 0; i < dependes.Length; i++)
{
AssetBundle.LoadFromFile("AssetBundles/" + dependes[i]);
}
if (ab != null)
{
//储存时的预制体名字
GameObject image = ab.LoadAsset<GameObject>("Image3");
Instantiate(image, transform);
}
}
卸载
卸载可以减少内存使用,有可能资源丢失
AssetBundle.Unload(true)卸载所有资源,即使有资源被使用着
(1,在关卡切换、场景切换的时候
(2,资源没被调用的时候
AssetBundle.Unload(false)卸载所有没被使用的资源
个别资源怎么卸载
(1,通过 Resources.UnloadUnusedAssets.
(2,场景切换的时候
一般还是用AssetBundle.Unload(true)
总结
1.unity将ab依赖(共有)的资源打包,会减少ab包的大小
2.unity的场景资源打包时,要与其它资源分开,单独打包成ab包
3.不同ab包如果将相同资源打包会报错
4.由于unity的依赖打包,所以加载ab包的同时要加载它的所有依赖
5…manifest里有依赖信息,ab文件夹里与其同名的ab包(AssetBundles)拥有所有ab包的信息
6.加载出的是预制体要实例化后才能使用
7.卸载ab包所有资源时,请保证场景中没有引用ab包中的资源
8.非托管资源加载时不会在内存中存在多个,使用的是享元模式,比如预制体,图片
Unity Asset Bundle Browser tool工具
这是一个AssetBundle的查看工具,是Unity官方发布的一个扩展工具,可以查看帮助打包AssetBundle和查看AssetBundle内容。可以去GitHub上下载
https://github.com/Unity-Technologies/AssetBundles-Browser
下载后直接将里面的Editor扩展工具拖入我们的Unity Project工程中
然后再窗口Window下找到并选择AssetBundle Browser选项,就可以打开看到我们AssetBundle 窗口了
以上是关于unity打包-1.Asset Bundle资源打包的主要内容,如果未能解决你的问题,请参考以下文章
Unity 5 官方打包管理工具 Asset Bundle Manager