• AssetBundle打包


    为热更新打基础(xlua olua)

    素材、源码链接:http://www.sikiedu.com/course/74/task/1812/show

    一、AssetBundle的定义和作用

    1,AssetBundle是一个压缩包包含模型、贴图、预制体、声音、甚至整个场景,可以在游戏运行的时候被加载;

    2,AssetBundle自身保存着互相的依赖关系;

    3,压缩包可以使用LZMA和LZ4压缩算法,减少包大小,更快的进行网络传输;

    4,把一些可以下载内容放在AssetBundle里面,可以减少安装包的大小;

    二、什么是AssetBundle?

    可以归为两点:

    1,它是一个存在于硬盘上的文件。可以称之为压缩包。这个压缩包可以认为是一个文件夹,里面包含了多个文件。这些文件可以分为两类:serialized file 和 resource files。(序列化文件和源文件)

    serialized file:资源被打碎放在一个对象中,最后统一被写进一个单独的文件(只有一个)

    resource files:某些二进制资源(图片、声音)被单独保存,方便快速加载

    2,它是一个AssetBundle对象,我们可以通过代码从一个特定的压缩包加载出来的对象。这个对象包含了所有我们当初添加到这个压缩包里面的内容,我们可以通过这个对象加载出来使用。

    三、AssetBundle包使用流程(简称AB)

    1,指定资源的AssetBundle属性,在unity编辑器右下角

    (xxxa/xxx)这里xxxa会生成目录,名字为xxx

    2,构建AssetBundle包

    3,上传AB包

    4,加载AB包和包里面的资源

    5-使用代码打包AssetBundle

    四、(代码部分)在Project中创建一个Editor的文件夹,在里面写编辑器拓展的代码

    CreateAssetBundle.cs

    using UnityEditor;

    using System.IO;

    public class CreateAssetBundle {

        [MenuItem("Assets/Build AssetBundles")]

        static void BuildAllAssetBundles()

        {

            //由于unity不会帮我们自动创建目录,所以我们需要自己创建

            string dir = "AssetBundles";

            if (Directory.Exists(dir) == false) //如果文件夹不存在

            {

                Directory.CreateDirectory(dir);

            }

            BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);

        }

    }

    再次打包时如果文字相同会自动覆盖

    五、AssetBundle打包注意事项

    1.生成两个文件,manifest文件的作用

    2.目录的划分  scene/wall

    六、AssetBundle的加载和使用

    新建空物体挂上LoadFromFile.cs

    using UnityEngine;

    public class LoadFromFile : MonoBehaviour {

        void Start () {

            AssetBundle ab= AssetBundle.LoadFromFile("AssetBundles/scene/cubewall.unity3d");

            //加载一个

            GameObject cubePrefab = ab.LoadAsset<GameObject>("cubeWall");

            Instantiate(cubePrefab);

            //遍历加载一个

            //Object[] objects= ab.LoadAllAssets();

            //foreach (Object item in objects)

            //{

            //    Instantiate(item);

            //}

        }

    }

    七、AssetBundle分组策略

    1,逻辑实体分组

    a,一个UI界面或者所有UI界面一个包(这个界面里面的贴图和布局信息一个包)

    b,一个角色或者所有角色一个包(这个角色里面的模型和动画一个包)

    c,所有的场景所共享的部分一个包(包括贴图和模型)

    2,按照类型分组

    所有声音资源打成一个包,所有shader打成一个包,所有模型打成一个包,所有材质打成一个包

    3,按照使用分组

    把在某一时间内使用的所有资源打成一个包。可以按照关卡分,一个关卡所需要的所有资源包括角色、贴图、声音等打成一个包。也可以按照场景分,一个场景所需要的资源一个包

    八、Assetbundle分组策略总结

    1,把经常更新的资源放在一个单独的包里面,跟不经常更新的包分离

    2,把需要同时加载的资源放在一个包里面

    3,可以把其他包共享的资源放在一个单独的包里面

         如:共同使用的贴图放在一个单独的包中,能优化项目

    4,把一些需要同时加载的小资源打包成一个包

    5,如果对于一个同一个资源有两个版本,可以考虑通过后缀来区分  v1  v2  v3  unity3dv1 unity3

    九、依赖打包

         即为讲解上一节的第三点:共同使用的放在一个单独的包中,能优化项目

    十、打包选项(AssetBundle压缩方式)

    1,Build的路径(随意只要是在硬盘上都可以的)

    2,BuildAssetBundleOptions

    BuildAssetBundleOptions.None:使用LZMA算法压缩,压缩的包更小,但是加载时间更长。使用之前需要整体解压。一旦被解压,这个包会使用LZ4重新压缩。使用资源的时候不需要整体解压。在下载的时候可以使用LZMA算法,一旦它被下载了之后,它会使用LZ4算法保存到本地上。

    BuildAssetBundleOptions.UncompressedAssetBundle:不压缩,包大,加载快

    BuildAssetBundleOptions.ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是我们可以加载指定资源而不用解压全部。

    注意使用LZ4压缩,可以获得可以跟不压缩想媲美的加载速度,而且比不压缩文件要小。

    BuildTarget

    选择build出来的AB包要使用的平

    十一、Manifest文件是干什么的?

    Assets:(所在文件)

    Dependences:(依赖文件)

    十二、资源的依赖关系

    先加载依赖包,再加载当前包

    十三、从内存里面加载AssetBundle

    四个加载的API

    1,AssetBundle.LoadFromMemory(从内存下载)

         /// <summary>

        ///LoadFromMemory(从内存中同步加载)

        /// </summary>

        void Start()

        {

            string path = "AssetBundles/scene/cubewall.unity3d";

            AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));

            GameObject cubePrefab = ab.LoadAsset<GameObject>("cubeWall");

            Instantiate(cubePrefab);

        }

       AssetBundle.LoadFromMemoryAsync

         /// <summary>

        /// 第一种加载方式:LoadFromMemoryAsync(从内存中异步加载)

        /// </summary>

        IEnumerator Start()

        {

            string path = "AssetBundles/scene/cubewall.unity3d";

            AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));

            yield return request;

            AssetBundle ab = request.assetBundle;

            GameObject cubePrefab = ab.LoadAsset<GameObject>("cubeWall");

            Instantiate(cubePrefab);

        }

    2,AssetBundle.LoadFromFile(从本地下载)

       AssetBundle.LoadFromFileAsync

         /// <summary>

        /// 第二种加载方式:LoadFromFile(从内存中异步加载)

        /// </summary>

        IEnumerator Start()

        {

            string path = "AssetBundles/scene/cubewall.unity3d";

            AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);

            yield return request;

            AssetBundle ab = request.assetBundle;

            //使用里面的资源

            var cubePrefab = ab.LoadAsset<GameObject>("cubeWall");

            Instantiate(cubePrefab);

        }

    3,WWW.LoadFromCacheOrDownload

    4,UnityWebRequest

    十四、使用WWW.LoadFromCacheOrDownload下载AssetBundle

         /// <summary>

        /// 第三种加载方式:www

        /// </summary>

        /// <returns></returns>

        IEnumerator Start()

        {

            string path = @"file:///F:经典学习案例,忘记了可以回头看的案例siki的AssetBundleAssetBundleProjectAssetBundlesscenecubewall.unity3d";

             //string path = @"http://localhost/AssetBundlesscenecubewall.unity3d";

            while (Caching.ready == false)

            {

                yield return null;

            }

            WWW www = WWW.LoadFromCacheOrDownload(path, 1);

            yield return www;

            if(string.IsNullOrEmpty(www.error)==false)

            {

                Debug.Log(www.error);

                yield break;

            }

            AssetBundle ab = www.assetBundle;

            //使用里面的资源

            var wallPrefab = ab.LoadAsset<GameObject>("cubeWall");

            Instantiate(wallPrefab);

        }

    十五、搭建简单的Server服务器

    使用NetBox2.exe可以方便把本文件夹做成网站

    使用记事本创建首页index.html

    十六、从服务器下载AssetBundle

    使用www和UnityWebRequest都可以

    十七、使用UnityWebRequest下载AssetBundle

    IEnumerator Start()

        {  

            string uri = @"file:///F:经典学习案例,忘记了可以回头看的案例siki的AssetBundleAssetBundleProjectAssetBundlesscenecubewall.unity3d";

            UnityWebRequest request = UnityWebRequest.GetAssetBundle(uri);

            yield return request.Send();

            //AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);

            AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;

            //使用里面的资源

            var wallPrefab = ab.LoadAsset<GameObject>("cubeWall");

            Instantiate(wallPrefab);

        }

    十八、从AssetBundle里面加载资源

    一般

    T objectFromBundle = bundleObject.LoadAsset<T>(assetName);

    GameObject

    GameObject gameObject =

    loadedAssetBundle.LoadAsset<GameObject>(assetName);

    所有资源

    Unity.Object[] objectArray =

    loadedAssetBundle.LoadAllAssets();

    -通过Manifest文件得到某个包的依赖

    加载Manifests文件可以处理资源的依赖

    AssetBundle assetBundle = AssetBundle.LoadFromFile(manifestFilePath);

    AssetBundleManifest manifest = assetBundle.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

    string[] dependencies = manifest.GetAllDependencies("assetBundle"); //Pass the name of the bundle you want the dependencies for.

    foreach(string dependency in dependencies)

    {

    AssetBundle.LoadFromFile(Path.Combine(assetBundlePath, dependency));

    }

    AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");

            AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

            //foreach (var item in manifest.GetAllDependencies("cube.unity3d"))

            //{

            //    print(name);

            //}

            string[] strs = manifest.GetAllDependencies("cube.unity3d");

            foreach (string name in strs)

            {

                print(name);

                AssetBundle.LoadFromFile("AssetBundles/" + name);

            }

    using System.Collections;

    using System.Collections.Generic;

    using System.IO;

    using UnityEngine;

    using UnityEngine.Networking;

    public class LoadFromFileExample : MonoBehaviour {

    private void Start()

        {

            AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");

            AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

    //foreach (var item in manifest.GetAllDependencies("cube.unity3d"))

    //{

    //    print(name);

    //}

    string[] strs = manifest.GetAllDependencies("scene/cap.unity3d");

    foreach (string name in strs)

            {

                print(name);

                AssetBundle.LoadFromFile("AssetBundles/" + name);

            }

        }

    }

    十九、AssetBundle的卸载

    卸载有两个方面

    1,减少内存使用

    2,有可能导致丢失

    所以什么时候去卸载资源

    AssetBundle.Unload(true)卸载所有资源,即使有资源被使用着

    (1,在关切切换、场景切换2,资源没被用的时候 调用)

    AssetBundle.Unload(false)卸载所有没用被使用的资源

    个别资源怎么卸载1,通过 Resources.UnloadUnusedAssets.  2,场景切换的时候

    二十、关于文件校验

    CRC MD5 SHA1

    相同点:

    CRC、MD5、SHA1都是通过对数据进行计算,来生成一个校验值,该校验值用来校验数据的完整性。

    不同点:

    1. 算法不同。CRC采用多项式除法,MD5和SHA1使用的是替换、轮转等方法;

    2. 校验值的长度不同。CRC校验位的长度跟其多项式有关系,一般为16位或32位;MD5是16个字节(128位);SHA1是20个字节(160位);

    3. 校验值的称呼不同。CRC一般叫做CRC值;MD5和SHA1一般叫做哈希值(Hash)或散列值;

    4. 安全性不同。这里的安全性是指检错的能力,即数据的错误能通过校验位检测出来。CRC的安全性跟多项式有很大关系,相对于MD5和SHA1要弱很多;MD5的安全性很高,不过大概在04年的时候被山东大学的王小云破解了;SHA1的安全性最高。

    5. 效率不同,CRC的计算效率很高;MD5和SHA1比较慢。

    6. 用途不同。CRC一般用作通信数据的校验;MD5和SHA1用于安全(Security)领域,比如文件校验、数字签名等。

    二十一、AssetBundle使用的一些问题

    Patching with AssetBundles(打补丁)

    1,依赖包重复问题

    a,把需要共享的资源打包到一起

    b,分割包,这些包不是在同一时间使用的

    c,把共享部分打包成一个单独的包

    2,图集重复问题

    3,Android贴图问题

    4,iOS文件处理重复fixed in Unity 5.3.2p2.

    二十二、AssetBundles浏览工具

    GitHub上面的一个工具https://github.com/Unity-Technologies/AssetBundles-Browser

    StreamingAssets文件夹里面的东西会被全部打包(放声音、图片)

    也把游戏中AssetBundle文件放到这个文件夹里面

    工具里面也有一个buildAssetBundle的方法,不用自己写了

    ----》》Window-AssetBundle Browser

    Image(16)

    我爱学习,学习使我快乐。
  • 相关阅读:
    C# 序列化技术详解《转》
    DataGridView中的DataGridViewComboBoxColumn使用浅析
    取EXCEL文件的3种方法
    教你几种在SQLServer中删除重复数据方法
    事件浅析
    迭代委托链
    C#调用耗时函数时显示进度条浅探
    启动公告【过时】
    在Web应用中接入微信支付的流程之极简清晰版
    VBoxManage: error: Cannot register the hard disk 解决办法
  • 原文地址:https://www.cnblogs.com/kerven/p/8118215.html
Copyright © 2020-2023  润新知