• AssetBundle打包


    一.简单的打包实现(打包游戏物体)。

    1.将需要打包的游戏物体制作成预制体,在预制体的Inspector面板最下方找到AssetBundle选项,在这里设置物体打包后的包名和后缀。名称为None代表不打包。

    2.添加打包脚本,脚本不需要继承Monobehavior。在菜单栏上添加打包选项。

    using System.IO;
    using UnityEditor;
    
    public class CreateAssetBundles
    {
        //使用一个静态方法进行打包,将这个方法添加到菜单栏
        [MenuItem("Assets/Build AssetBundles")]
        static void BuildAllAssetBundles()
        {
            //因为打包时不会自动创建路径,所以检验打包路径是否存在,不存在需要先创建打包路径
            string dir = "AssetBundles";
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            //打包
            BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
        }
    }

    3.打包

     4.在刚才设置的打包文件夹下可以查看是否打包成功

    二.资源的加载

    1.添加空物体,挂载一个用于加载资源的脚本

    2.在脚本中加载资源

    public class LoadFromFileExample : MonoBehaviour
    {
        // Start is called before the first frame update
        void Start()
        {
            //加载资源,加载后的内容保存为AssetBundle对象
            AssetBundle assetBundle = AssetBundle.LoadFromFile("AssetBundles/wall.unity3d");
            //取出资源,资源的类型时GameObject,名称是Wall
            GameObject wallPrefab = assetBundle.LoadAsset<GameObject>("Wall");
            //实例化取出的游戏物体
            Instantiate(wallPrefab);
        }
    
    }

    三.更多的打包和加载资源的选择

    1.打包目录划分:在unity中的Inspector窗口下确定填写打包后包名时可以通过"/"进行目录划分。不同的资源可以指定相同的包名和后缀,也就是同一个包中可以包含多个资源。

    2.AssetBundle分组策略:可以采用按照逻辑实体分组、按照类型分组、按照使用分组等分组策略,根据项目的实际需求确定具体的分组策略。通常遵循以下分组原则:

    1)把经常更新的资源和不常更新的资源分开,减少包的大小

    2)把需要同时加载的资源放在一起,提高加载效率

    3)把和其他包共享的资源单独放置,避免重复打包

    4)把一些需要同时加载的小资源放在一起,提高加载效率

    5)可以通过后缀区分同一个资源的不同版本

    3.BuileAssetBundleOptions选项

    官方API:

     常用选项:

    1)BuildAssetHBundleOptions.None:默认使用LZMA算法压缩。

    2)BuileAssetBundleOptions.UncompressedAssetBundle:不压缩

    3)BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩

    LZMA压缩和LZ4压缩:

    LZMA压缩比LZ4压缩后的包体积更小,压缩率更高,但是也意味着解压缩的时间更长,加载时间更长。而且LZMA压缩在解压缩时只能整体解压,如果只是想使用压缩文件中的一小部分内容的话会造成资源浪费,因此一般在下载时使用LZMA压缩算法,下载后再使用LZ4算法保存到本地。

    4.minifest文件详解

     5.加载AssetBundle的其他方式

    1)AssetBundle.LoadFromMemoryAsync方法:加载二进制字节数组

    异步的方式

        IEnumerator Start()
        {
            AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes("AssetBundles/wall.unity3d"));
            yield return request;
            AssetBundle ab = request.assetBundle;
    
            GameObject wallPrefab = ab.LoadAsset<GameObject>("Wall");
            Instantiate(wallPrefab);
        }

    同步的方式

        void Start()
        {
            AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes("AssetBundles/wall.unity3d"));
    
            GameObject wallPrefab = ab.LoadAsset<GameObject>("Wall");
            Instantiate(wallPrefab);
        }

    2)AssetBundle.LoadFromFile方法:直接从文件加载

    异步的方式

        IEnumerator Start()
        {
            AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync("AssetBundles/wall.unity3d");
            yield return request;
            AssetBundle ab = request.assetBundle;
    
            GameObject wallPrefab = ab.LoadAsset<GameObject>("Wall");
            Instantiate(wallPrefab);
        }

    同步的方式

        void Start()
        {
            AssetBundle ab = AssetBundle.LoadFromFile("AssetBundles/wall.unity3d");
    
            GameObject wallPrefab = ab.LoadAsset<GameObject>("Wall");
            Instantiate(wallPrefab);
        }

    3)WWW.LoadFromCacheOrDownload方法:从服务器或本地缓存加载(即将弃用)

        IEnumerator Start()
        {
            while (!Caching.ready)
            {
                yield return null;
            }
    
            WWW www = WWW.LoadFromCacheOrDownload(@"file:\D:UnityProjectsAssetBundleLearningAssetBundleswall.unity3d", 1);
            AssetBundle ab = www.assetBundle;
    
            GameObject wallPrefab = ab.LoadAsset<GameObject>("Wall");
            Instantiate(wallPrefab);
        }

    4)UnityWebRequestAssetBundle方法:从服务器加载(UnityWebRequest方法弃用)

        IEnumerator Start()
        {
            UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri: @"file:\D:UnityProjectsAssetBundleLearningAssetBundleswall.unity3d");
            yield return request.SendWebRequest();
            AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
    
            GameObject wallPrefab = ab.LoadAsset<GameObject>("Wall");
            Instantiate(wallPrefab);
        }
        IEnumerator Start()
        {
            UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(uri: @"file:\D:UnityProjectsAssetBundleLearningAssetBundleswall.unity3d");
            yield return request.SendWebRequest();
            AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;
    
            GameObject wallPrefab = ab.LoadAsset<GameObject>("Wall");
            Instantiate(wallPrefab);
        }

    6.manifest文件的加载

        void Start()
        {
            //加载manifest文件
            AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");
            AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    
            //获取所有包名称
            foreach(string name in manifest.GetAllAssetBundles())
            {
                print(name);
            }
        }
        void Start()
        {
            //加载manifest文件
            AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");
            AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    
            //获取"wall.unity3d"这个包的所有依赖
            foreach (string name in manifest.GetAllDependencies("wall.unity3d"))
            {
                print(name);
                //加载依赖文件
                AssetBundle.LoadFromFile("AssetBundles/" + name);
            }
        }

    7.卸载AssetBundle包

    使用AssetBundle.Unload(false)AssetBundle.Unload(true)来卸载资源,参数代表是否将正在使用中的已加载资源一并卸载。但是需要注意的是,如果使用AssetBundle.Unload(false)卸载资源,正在使用中的资源没有被卸载,这些正在使用中的资源就会一直占用内存,为避免内存被一直占用,一般使用AssetBundle.Unload(true)卸载资源,如果一定要使用AssetBundle.Unload(false)卸载资源,可以在合适的时间调用Resources.UnloadUnusedAssets卸载资源或者以非附加的形式加载场景,这样会自动调用Resources.UnloadUnusedAssets卸载资源。

    8.文件校验

    校验文件通常有CRC、MD5、SHA1三种算法生成校验值,可以从manifest文件中看到,AssetBundle使用的是CRC算法生成校验码。

    9.常见问题

    1)依赖包重复问题

    解决:把共享的资源一起打包/根据使用时间分割包/共享的部分打包到一起

    2)图集重复问题

  • 相关阅读:
    用html5标记一段文章模块
    自定义事件
    html5表单
    对canvas封装的js库
    canvas
    第五周进度总结
    第七周进度总结
    大道至简阅读笔记
    第六周进度总结
    第三周进度总结
  • 原文地址:https://www.cnblogs.com/movin2333/p/14359140.html
Copyright © 2020-2023  润新知