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+NGUI性能优化方法总结

unity5打包机制下,一种资源打ab和资源管理的方案

Unity 5 官方打包管理工具 Asset Bundle Manager

unity-------------------打包BuildAssetBundles的使用

Unity 加载资源

Unity中 动态加载 Resources.Load()和Asset Bundle 的区别