美文网首页
[个人框架 C_Framework] 快速打包AssetBund

[个人框架 C_Framework] 快速打包AssetBund

作者: hh5460 | 来源:发表于2018-11-02 12:53 被阅读0次

    打包AssetBundle其实是一个很简单的过程,无非是设置一下AssetBundleName,然后调用一下BuildPipeline.BuildAssetBundles...但是实际上呢,从功能上来讲已经是实现了,实际上更多的是要考虑业务上的问题,假设每次打个bundle100多M,哪些需要更新,哪些不需要更新,哪些需要分类,哪些不需要其实都是应该好好考虑的问题...
    给大家介绍下我自己平时是如何打包AssetBundle并且使用的...

    演示:

    我会将需要打包的文件放到一个ResourcesBundles的文件夹下,不需要对其设置任何东西,也不需要手动修改AssetBundleName,我使用了文件夹对其分类
    1.比如common_unity,这个文件夹下,首先它们是一类,假设是一些通用的预制之类的,然后由于后面加了_unity,所以他们会被打成一个大的.asset文件
    2.然后再看role1s文件夹,他们也是一类,都是角色,不同的是这个文件夹名称后面没有加_unity,所以虽然它们下面的role1_001,role1_002...等等每一个都会被打成单独的assetbundle,这样做的好处是,可能100个角色只有一两个需要更新,那到时候更新变化的一两个即可
    3.再看role2s_unity,那么其实跟1同理,他们都会被打成一个asset包

    项目路径
    一键打包
    分好类后我就可以一键打包了,同上图,我们首先来看看打包完成之后是什么样子呢,我把打包完成之后的文件夹也指定在了Assets/路径下了,看下图
    打包后
    首先是打包时指定对应平台文件夹WIN,然后看role1s文件夹,跟我们预想的一样,打包在同一个文件夹下,然后每个角色一个单独的.asset文件,再看role2s_unitycommon_unity虽然每一个都包含多个物体但是打成了一个.asset...
    分类确实是分完了,但是如何知道哪些要更新,哪些不要更新呢,大家看到哪个updatelist文件没有,实际上每次一键打包完成之后都会读取每个.asset对应的.manifest配置信息,然后存储到updatelist这个文件夹中,即这个文件夹包含了这次打包的所有文件校验信息,那么实际上将整个WIN放到服务器上,然后每次更新先请求updatelist文件与本地的做对比,就可以具体到哪一个文件需要更新了,可以按需下载了,我们看下updatelist的文件结构如下...
    [{
        "name": "common",
        "path": "ABS/WIN/common",
        "crc": "3351467148",
        "hash": "2a1ae689ec6de75242619cca95b4d372",
        "items": "aaa|ccc|bbb"
    },
     {
        "name": "empty",
        "path": "ABS/WIN/empty",
        "crc": "1978368619",
        "hash": "0c63038f67eb915b7ddcdcd077fcd26e",
        "items": "empty"
    }, 
     {
        "name": "role2s",
        "path": "ABS/WIN/role2s",
        "crc": "836200448",
        "hash": "08ca3124c3921c42fd216fb7eff71d21",
        "items": "role2_001|role2_004|role2_005|role2_003|role2_002"
    },
     {
        "name": "role1_001",
        "path": "ABS/WIN/role1s/role1_001",
        "crc": "3263454155",
        "hash": "bfd6c79dcdd02c844baba35a94bf2efa",
        "items": "role1_001"
    }, 
     {
        "name": "role2_002",
        "path": "ABS/WIN/role1s/role2_002",
        "crc": "3257236986",
        "hash": "d2ad52b0ed5253f7055a6de0f9640695",
        "items": "role2_002"
    },
     {
        "name": "role3_003",
        "path": "ABS/WIN/role1s/role3_003",
        "crc": "1783149555",
        "hash": "6bf370de4435843658b1287492147fbf",
        "items": "role3_003"
    },
     {
        "name": "role4_004",
        "path": "ABS/WIN/role1s/role4_004",
        "crc": "166964991",
        "hash": "ee84f8f20cd6f9cd0560892e2f942ed2",
        "items": "role4_004"
    }, 
     {
        "name": "role6_005",
        "path": "ABS/WIN/role1s/role6_005",
        "crc": "1113472926",
        "hash": "ae54098c738592ad6294c05efb8ebdf0",
        "items": "role6_005"
    }]
    

    上代码

    PS注意事项:引用了litjson库,请自行百度下载,或者替换成别的库都OK

    1.通用路径常量,即我用这个脚本存储所有的常用路径

    using UnityEngine;
    
    public class ConstantVariable
    {
        //存储StreamingAssetsPath路径
        public static string StreamingAssetsPathWWW
        {
            get
            {
                string Path = "";
    
    #if UNITY_EDITOR  //编辑器平台
                {
                    //On Windows use:
                    Path = "file://" + Application.dataPath + "/StreamingAssets/";          //注意,由于此处assets后面已经加了/,所以后面跟的文件夹不要再加/
    
                }
    #elif UNITY_IPHONE
                {
                    //On iOS, use:
                    Path = "file://"+Application.dataPath + "/Raw/";                        //注意,由于此处assets后面已经加了/,所以后面跟的文件夹不要再加/                           
                }
    #elif UNITY_ANDROID
                {
                    //On Android, use:
                    Path = "jar:file://" + Application.dataPath + "!/assets/";           
                }
    #endif         
                return Path;
            }
        }
        //存储PersistentDataPath路径
        public static string PersistentDataPathWWW
        {
            get
            {
                string Path = "";
    
    #if UNITY_EDITOR  //编辑器平台
                {
                    //On Windows use:
                    Path = "file://" + Application.persistentDataPath + "/";
    
                }
    #elif UNITY_IPHONE
                {
                    //On iOS, use:
                    Path = "file://"+Application.persistentDataPath + "/";                          
                }
    #elif UNITY_ANDROID
                {
                    //On Android, use:
                    Path = "jar:file://" + Application.persistentDataPath + "/";           
                }
    #endif         
                return Path;
            }
        }
    
        //存储StreamingAssetsPath路径
        public static string StreamingAssetsPathFile
        {
            get
            {
                string Path = "";
    
    #if UNITY_EDITOR  //编辑器平台
                {
                    //On Windows use:
                    Path = Application.dataPath + "/StreamingAssets/";          //注意,由于此处assets后面已经加了/,所以后面跟的文件夹不要再加/
    
                }
    #elif UNITY_IPHONE
                {
                    //On iOS, use:
                    Path = Application.dataPath + "/Raw/";                              //注意,由于此处assets后面已经加了/,所以后面跟的文件夹不要再加/                           
                }
    #elif UNITY_ANDROID
                {
                    //On Android, use:
                    Path = Application.dataPath + "!/assets/";           
                }
    #endif         
                return Path;
            }
        }
        //存储PersistentDataPath路径
        public static string PersistentDataPathFile
        {
            get
            {
                return Application.persistentDataPath + "/";
            }
        }
    
        //打包到的文件夹名
        public static string buildPathDir
        {
            get
            {
    #if UNITY_ANDROID  //编辑器平台
                return "ABS/ANDROID/";
    #elif UNITY_IPHONE
                return "ABS/IOS/";
    #else
                return "ABS/WIN/";
    #endif
            }
        }
    
        //打包到的整体路径名
        public static string build2Path
        {
            get
            {
                return Application.dataPath + "/" + buildPathDir;
            }
        }
    
        //需要打包的文件夹名(即当前目录下的内容是需要被打包的)
        public static string needBundlePathDir
        {
            get
            {
                return "ResourcesBundles/";
            }
        }
    
        //需要打包的路径名
        public static string needBundle2Path
        {
            get
            {
                return Application.dataPath + "/" + needBundlePathDir;
            }
        }
    
        //服务器地址
        public static string serverHostAddress
        {
            get
            {
                return "http://localhost:8080/";
            }
        }
    
        //更新列表地址
        public static string updateListFileName
        {
            get
            {
                return "updatelist.bin";
            }
        }
    }
    

    2.最后存储bundle信息的类##

    /// <summary>
    /// 存储打包后Bundle信息
    /// </summary>
    public class AssetBundleItemInfo
    {
        //bundle名称
        public string name;
        //bundle路径
        public string path;
        //bundle文件的crc校验
        public string crc;
        //bundle文件的hash校验
        public string hash;
        //该bundle下包含的所有物体子集 | 分隔
        public string items;
    }
    

    3.一键打包AssetBundle代码,PS:注意放到Editor文件夹下##

    using UnityEngine;
    using System.IO;
    using System.Collections.Generic;
    using UnityEditor;
    using System.Text.RegularExpressions;
    
    /// <summary>
    /// 创建AssetBundle
    /// </summary>
    public class CreateAssetBundle : MonoBehaviour
    {
        //打包到的平台
        static BuildTarget target;
    
        //打包的其他选择项目
        static BuildAssetBundleOptions buildAssetBundleOptions = BuildAssetBundleOptions.None;
    
        //打包到IPhone平台
        [MenuItem("C_Tools/AB_Packager/Build_2_IPhone")]
        public static void Build_2_IPhone()
        {
            target = BuildTarget.iOS;
            BuildAssetResource(target);
        }
    
        //打包到Android平台
        [MenuItem("C_Tools/AB_Packager/Build_2_Android")]
        public static void Build_2_Android()
        {
            target = BuildTarget.Android;
            BuildAssetResource(target);
        }
    
        //打包到Windows平台
        [MenuItem("C_Tools/AB_Packager/Build_2_Windows")]
        public static void Build_2_Windows()
        {
            target = BuildTarget.StandaloneWindows;
            BuildAssetResource(target);
        }
    
        /// <summary>
        /// 开始打包资源
        /// </summary>
        /// <param name="target"></param>
        private static void BuildAssetResource(BuildTarget target)
        {
            //设置AssetName
            SetResourcesBundlesAssetName();
    
            //文件已经存在就删除
            if (Directory.Exists(ConstantVariable.build2Path))
            {
                Directory.Delete(ConstantVariable.build2Path, true);
            }
            //文件不存在就创建
            if (!Directory.Exists(ConstantVariable.build2Path))
            {
                Directory.CreateDirectory(ConstantVariable.build2Path);
            }
    
            //开始打包
            BuildPipeline.BuildAssetBundles(ConstantVariable.build2Path, buildAssetBundleOptions, target);
            //生成配置文件,标记文件的路径和是否需要更新
            CreateCheckFile();
        }
    
        //打包完成后生成校验文件
        private static void CreateCheckFile()
        {
            //记录打包项目
            List<AssetBundleItemInfo> lstItems = new List<AssetBundleItemInfo>();
            //显示生成校验文件信息
            EditorUtility.DisplayProgressBar("生成校验文件", "正在生成校验文件...", 0.9f);
    
            //获取当前打包目录下的所有manifest文件
            string[] files = Directory.GetFiles(ConstantVariable.build2Path, "*.manifest", SearchOption.AllDirectories);
    
            //遍历当前所有manifest文件
            for (int i = 0; i < files.Length; i++)
            {
                //将"\\"替换成"/"
                string filepath = files[i].Replace("\\", "/");
    
                //此处防止记录ABS/IOS/IOS的manifest
                if (filepath.Contains(ConstantVariable.buildPathDir + ConstantVariable.buildPathDir.Split('/')[1]))
                {
                    continue;
                }
    
                Debug.Log(filepath);
    
                //创建一个AssetBundleItemInfo信息
                AssetBundleItemInfo assetBundleItemInfo = new AssetBundleItemInfo();
                //设置AssetBundleItemInfo的名字
                assetBundleItemInfo.name = Path.GetFileNameWithoutExtension(filepath);
                //记录当前AssetBundle的路径信息
                string filePath = filepath.Substring(filepath.LastIndexOf(ConstantVariable.buildPathDir));
                assetBundleItemInfo.path = filePath.Substring(0, filePath.LastIndexOf(".manifest"));
    
                //读取当前.manifest中的信息
                string fileContent = File.ReadAllText(filepath);
                //将当前的被打包路径替换成打包后的路径 即打包前 ResourcesBundles 替换成打包后 ABS,并且将"_unity"的替换为空
                fileContent = fileContent.Replace("Assets/" + ConstantVariable.needBundlePathDir, ConstantVariable.buildPathDir).Replace("_unity", "");
                //取出当前的assetbundle的CRC信息
                assetBundleItemInfo.crc = Regex.Match(fileContent, @"CRC:.(\d*)").Groups[1].ToString();
                //取出当前的assetbundle的Hash信息
                assetBundleItemInfo.hash = Regex.Match(fileContent, @"Hash:.(.*)\s{3}Type").Groups[1].ToString();
                
                //记录当前 assetbundle中包含的所有物体
                string[] items = Regex.Match(fileContent, @"Assets:\s((-\s.*\s)*)Dep").Groups[1].ToString().Replace("- ", "").Replace("\n", "|").TrimEnd('|').Split('|');
                string result = string.Empty;
                for (int j = 0; j < items.Length; j++)
                {
                    result += Path.GetFileNameWithoutExtension(items[j]) + "|";
                }
                assetBundleItemInfo.items = result.TrimEnd('|');
    
                //将assetBundleItemInfo添加到村粗的集合中
                lstItems.Add(assetBundleItemInfo);
            }
    
            //生成json校验文件并写入updatelist.bin文件
            string json = LitJson.JsonMapper.ToJson(lstItems);
            File.WriteAllText(ConstantVariable.build2Path + ConstantVariable.updateListFileName, json);
    
            EditorUtility.ClearProgressBar();
        }
    
        /// <summary>
        /// 设置AssetName
        /// </summary>
        static string filePath = "";
        static string assetBundleName = "";
        public static void SetResourcesBundlesAssetName()
        {
            //记录当前需要打包的路径
            string fullPath = ConstantVariable.needBundle2Path;
            if (Directory.Exists(fullPath))   //如果当前路径存在
            {
                //开始设置名称
                EditorUtility.DisplayProgressBar("设置AssetBundleName", "正在设置AssetName名称中...", 0f);
    
                //获取当前路径下的所有文件
                var dir = new DirectoryInfo(fullPath);
                var files = dir.GetFiles("*", SearchOption.AllDirectories);
    
                //遍历文件
                for (var i = 0; i < files.Length; ++i)
                {
    
                    EditorUtility.DisplayProgressBar("设置AssetBundleName", "正在设置AssetName名称中...", i * 1.0f / files.Length);
                    filePath = files[i].FullName.Replace("\\", "/");
                    filePath = filePath.Substring(filePath.LastIndexOf(ConstantVariable.needBundlePathDir)+ ConstantVariable.needBundlePathDir.Length);
    
                    //排除后缀为.meta的文件
                    if (!filePath.EndsWith(".meta"))
                    {
                        var asset = AssetImporter.GetAtPath("Assets/" + ConstantVariable.needBundlePathDir + filePath);
                        assetBundleName = filePath.Substring(0, filePath.LastIndexOf(".")).ToLower();
    
                        //如果包含着"_unity"则将该目录下的打成同一个包
                        if (assetBundleName.Contains("_unity"))   
                        {
                            assetBundleName = assetBundleName.Substring(0, assetBundleName.IndexOf("_unity"));
                        }
    
                        if (asset && asset.assetBundleName != assetBundleName)
                        {
                            asset.assetBundleName = assetBundleName;
                        }
                    }
                }
                EditorUtility.ClearProgressBar();
            }
        }
    }
    

    打包说完了,我们来说说使用

    上面我们介绍了一键打包,那么打包之后如何使用呢,我这里也有一套自己的解决方案,其实打包完成之后大家看懂了也就知道该怎么用了...

    PS注意事项:

    1. 引用了litjson库,请自行百度下载,或者替换成别的库都OK
    2. 引用了BestHttp的Http请求库,个人觉得比unity自带的www和UnityWebRequest好用很多
    3. 继承自SingleFramework,不理解这是啥的请参考我之前的文章单例那篇
    下载更新存储到本地
    using System.Collections.Generic;
    using BestHTTP;
    using System.IO;
    using System;
    using LitJson;
    using UnityEngine;
    
    //AssetBundle管理器
    public class AssetBundleManager : SingleFramework<AssetBundleManager>
    {
        #region 下载AssetBundle
        //服务器存储的列表地址
        string serverUpdateListAddress;
        //本地存储的列表地址
        string localUpdateListAddress;
    
        List<AssetBundleItemInfo> lstAssetBundleItemInfo;    //待更新列表
    
        Queue<string> queuePathWaitingDownload;              //等待下载列表
    
        Action<float, int> dlt_FirstDownloadStart;           //第一个开始下载的时候 <首个下载资源长度,总的下载.asset个数>
        Action<string, HTTPRequest, float, float> dlt_DownloadProgress;  //当前单个asset下载进度 <包名,下载request对象,当前已下载长度,总长度>
        Action<int, int> dlt_DownloadUpdateOneOver;          //单个下载完成委托 <当前已经下载完成个数,还需要下载个数>
        Action dlt_DownloadUpdateALLOver;                    //全部下载完成委托
    
        int NeedDownLoadALLCounter = 0;              //需要下载总数
        int NowOverDowLoadCounter = 0;               //当前完成总数
    
        /// <summary>
        /// 检测更新列表并下载
        /// </summary>
        /// <param name="_InitStart">即将开始请求服务器时的委托</param>
        /// <param name="_FirstDownloadStart">第一个资源开始下载时的委托</param>
        /// <param name="_DownloadProgress">单个asset包下载进度更新的委托</param>
        /// <param name="_DownloadUpdateOneOver">当一个资源下载完成后的委托</param>
        /// <param name="_DownloadUpdateOver">所有资源下载完成后的委托</param>
        public void CheckUpdateList(Action _InitStart = null, Action<float, int> _FirstDownloadStart = null, Action<string, HTTPRequest, float, float> _DownloadProgress = null, Action<int, int> _DownloadUpdateOneOver = null, Action _DownloadUpdateOver = null)
        {
            if (_InitStart != null)     //初始化的委托,一般用来显示更新界面
            {
                _InitStart();
            }
    
            dlt_FirstDownloadStart = _FirstDownloadStart;        //绑定下载之前的委托
            dlt_DownloadUpdateOneOver = _DownloadUpdateOneOver;  //绑定单个加载完成的委托
            dlt_DownloadUpdateALLOver = _DownloadUpdateOver;     //绑定所有加载完成的委托
            dlt_DownloadProgress = _DownloadProgress;            //绑定进度更新的委托
    
            //本地updatelist.bin
            localUpdateListAddress = ConstantVariable.PersistentDataPathFile + ConstantVariable.buildPathDir + ConstantVariable.updateListFileName;
    
            //服务器updatelist.bin
            serverUpdateListAddress = ConstantVariable.serverHostAddress + ConstantVariable.buildPathDir + ConstantVariable.updateListFileName;
    
            //先去校验updatelist列表,查看需要更新的项目,没变化就不更新
            HTTPRequest httpRequest = new HTTPRequest(new System.Uri(serverUpdateListAddress), HTTPMethods.Get, false, true, (req, res) =>
            {
                if (res != null && !string.IsNullOrEmpty(res.DataAsText))
                {
                    //从服务器下载的更新列表
                    lstAssetBundleItemInfo = JsonMapper.ToObject<List<AssetBundleItemInfo>>(res.DataAsText.ToString());
    
                    //实例化下载队列
                    queuePathWaitingDownload = new Queue<string>();
    
                    //如果本地的列表文件不存在则需要全部更新
                    if (!File.Exists(localUpdateListAddress))
                    {
                        //需要下载所有,添加到队列
                        for (int i = 0; i < lstAssetBundleItemInfo.Count; i++)
                        {
                            queuePathWaitingDownload.Enqueue(lstAssetBundleItemInfo[i].path);
                        }
                    }
                    else//即服务器和本地都有updatelist.bin,则对比两个文件,差异化下载
                    {
    
                        string fileTxt = File.ReadAllText(localUpdateListAddress);
                        List<AssetBundleItemInfo> lstlocalFileInfo = JsonMapper.ToObject<List<AssetBundleItemInfo>>(fileTxt);
                        //比较下载不存在的就好
    
                        //对比而本地列表和服务器列表
                        for (int i = 0; i < lstAssetBundleItemInfo.Count; i++)
                        {
                            bool thisExist = false;
                            for (int j = 0; j < lstlocalFileInfo.Count; j++)
                            {
                                //是否存在相同文件需要比较
                                if (lstAssetBundleItemInfo[i].path == lstlocalFileInfo[j].path)              //本地存在的则比较如果crc或者hash不同或者不存在
                                {
                                    thisExist = true;
                                    if (lstAssetBundleItemInfo[i].crc != lstlocalFileInfo[j].crc || lstAssetBundleItemInfo[i].hash != lstlocalFileInfo[j].hash || !CheckFileExist(lstAssetBundleItemInfo[i].path))
                                    {
                                        queuePathWaitingDownload.Enqueue(lstAssetBundleItemInfo[i].path);    //跟服务器文件不一致下载新的
                                    }
                                    break;
                                }
                            }
                            if (!thisExist) //表示服务器存在项目但是本地不存在则直接下载新的
                            {
                                queuePathWaitingDownload.Enqueue(lstAssetBundleItemInfo[i].path);
                            }
                        }
                    }
    
                    //将新服务器新的列表添加到下载队尾
                    queuePathWaitingDownload.Enqueue(ConstantVariable.buildPathDir + ConstantVariable.updateListFileName);
                    NeedDownLoadALLCounter = queuePathWaitingDownload.Count;   //总的需要下载数
                    NowOverDowLoadCounter = 0;                                 //当前已下载
    
                    //开始递归下载
                    DownLoadUpdateResources_Recursion();
                }
            });
            httpRequest.Send();
        }
    
        //递归下载
        void DownLoadUpdateResources_Recursion()
        {
            if (queuePathWaitingDownload.Count == 0)
            {
                //表示所有都已下载完成
                if (dlt_DownloadUpdateALLOver != null)
                {
                    dlt_DownloadUpdateALLOver();       //执行更新完成的回调
                }
            }
            else if (queuePathWaitingDownload != null)
            {
                //取出包路径
                string packagePath = queuePathWaitingDownload.Dequeue();
                //拼接成服务器下载地址
                string downloadURL = ConstantVariable.serverHostAddress + packagePath;
                //开始下载
                HTTPRequest httpRequest = new HTTPRequest(new System.Uri(downloadURL), HTTPMethods.Get, false, true, (req, res) =>
                {
                    byte[] byteData = res.Data;
    
                    //创建文件路径
                    string fullPath = Path.GetDirectoryName(ConstantVariable.PersistentDataPathFile + "/" + GetRelativeAddress(downloadURL));
                    if (!Directory.Exists(fullPath))
                    {
                        DirectoryInfo di = new DirectoryInfo(fullPath);
                        di.Create();
                    }
    
                    //创建文件
                    FileInfo fileInfo = new FileInfo(ConstantVariable.PersistentDataPathFile + "/" + GetRelativeAddress(downloadURL));
                    FileStream fs = fileInfo.Create();
                    fs.Write(byteData, 0, byteData.Length);
                    fs.Flush();
                    fs.Dispose();
    
                    req.Dispose();
                    res.Dispose();
    
                    NowOverDowLoadCounter++;                        //已经完成的下载数+1
                    if (dlt_DownloadUpdateOneOver != null)          //每完成一个执行回调
                    {
                        dlt_DownloadUpdateOneOver(NowOverDowLoadCounter, NeedDownLoadALLCounter);
                    }
    
                    DownLoadUpdateResources_Recursion();
                });
                httpRequest.OnProgress = (httpReq, proNow, proAll) =>
                {
                    if (dlt_DownloadProgress != null)
                    {
                        //下载资源更新
                        if (dlt_FirstDownloadStart != null)
                        {
                            dlt_FirstDownloadStart(proAll * 1f / (1024 * 1024), queuePathWaitingDownload.Count + 1);         //只会在首次执行,因为只会执行一次
                            dlt_FirstDownloadStart = null;
                        }
                        dlt_DownloadProgress(GetAddressName(downloadURL), httpReq, proNow * 1f / (1024 * 1024), proAll * 1f / (1024 * 1024));
                    }
                };
                httpRequest.Send();
            }
        }
    
        //获取相对路径
        string GetRelativeAddress(string downloadURL)
        {
            return downloadURL.Substring(ConstantVariable.serverHostAddress.Length);
        }
    
        //获取文件名
        string GetAddressName(string downloadURL)
        {
            return Path.GetFileName(GetRelativeAddress(downloadURL));
        }
    
        //获取文件名不包含后缀
        string GetAddressNameWithoutExtention(string downloadURL)
        {
            return Path.GetFileNameWithoutExtension(GetRelativeAddress(downloadURL));
        }
    
        //检测本地是否存在此文件
        bool CheckFileExist(string fileUrl)
        {
            if (File.Exists(ConstantVariable.PersistentDataPathFile + fileUrl))
            {
                return true;
            }
            return false;
        }
    
        #endregion
    
        #region 加载AssetBundle
    
        /// <summary>
        /// 从本地获取所有的AssetBundle信息
        /// </summary>
        List<AssetBundleItemInfo> _lstAssetBundleItemInfos;
        public List<AssetBundleItemInfo> lstAssetBundleItemInfos
        {
            get
            {
                if (_lstAssetBundleItemInfos == null)
                {
                    string json = File.ReadAllText(ConstantVariable.PersistentDataPathFile + ConstantVariable.buildPathDir + ConstantVariable.updateListFileName);
                    _lstAssetBundleItemInfos = JsonMapper.ToObject<List<AssetBundleItemInfo>>(json);
                }
                return _lstAssetBundleItemInfos;
            }
        }
    
        //根据名字加载Asset
        public T LoadAssetWithPath<T>(string packName, string assetName, bool isUnload = false, bool isInstantiate = false) where T : UnityEngine.Object
        {
            AssetBundle assetBundle = AssetBundle.LoadFromFile(ConstantVariable.PersistentDataPathFile + ConstantVariable.buildPathDir + packName);
            T target = null;
            if (isInstantiate)
            {
                target = Instantiate(assetBundle.LoadAsset<T>(assetName.ToLower()));
            }
            else
            {
                target = assetBundle.LoadAsset<T>(assetName.ToLower());
            }
            assetBundle.Unload(isUnload);
            return target;
        }
    
        //根据名字从池中加载,没有就创建然后加入到CPool池中
        public GameObject LoadAssetGameobjectWithPool(string packName, string assetName, int preloadNum = 2, int limitNum = 20, int intervalTimeGC = 30, int oneShotGCNum = 1)
        {
            GameObject target = null;
            if (!C_Pool.Instance.ContainsPool(assetName))
            {
                PoolItemInfo pii = new PoolItemInfo();
                pii.TargetName = assetName;
                pii.PreloadNums = preloadNum;
                pii.LimitNums = limitNum;
                pii.IntervalTimeGC = intervalTimeGC;
                pii.OneShotGCNum = oneShotGCNum;
                pii.AssetBundlePackageName = packName;
                C_Pool.Instance.Add2Pool(pii);
            }
            target = C_Pool.Instance.GetPoolItem(assetName).DePool();
            return target;
        }
    
        //根据Asset包名获取对应的package路径
        public string GetAssetPackageFullPathWithPackageName(string PackageName)
        {
            PackageName = "/" + PackageName;
            for (int i = 0; i < lstAssetBundleItemInfos.Count; i++)
            {
                if (lstAssetBundleItemInfos[i].path.ToLower().IndexOf(PackageName) != -1)
                {
                    return lstAssetBundleItemInfos[i].path;
                }
            }
            return "";
        }
    
        //同上不包括自己包的名称
        public string GetAssetPackageWithOutMePathWithPackageName(string PackageName)
        {
            string result = GetAssetPackageFullPathWithPackageName(PackageName);
            int index = result.LastIndexOf('/');
            if (index != -1)
            {
                result = result.Substring(0, index + 1);
            }
            return result;
        }
    
        //根据物体名获取对应的package路径
        public string GetAssetPackageFullPathWithObjectName(string ObjectName)
        {
            ObjectName = "|" + ObjectName + "|";
            for (int i = 0; i < lstAssetBundleItemInfos.Count; i++)
            {
                if (("|" + lstAssetBundleItemInfos[i].items.ToLower() + "|").IndexOf(ObjectName) != -1)
                {
                    return lstAssetBundleItemInfos[i].path;
                }
            }
            return "";
        }
    
        //同上不包括自己包的名称
        public string GetAssetPackageWithOutMePathWithObjectName(string ObjectName)
        {
            string result = GetAssetPackageFullPathWithObjectName(ObjectName);
            int index = result.LastIndexOf('/');
            if (index != -1)
            {
                result = result.Substring(0, index + 1);
            }
            return result;
        }
    
        #endregion
    }
    
    调用方法
    下载调用
    AssetBundleManager.Instance.CheckUpdateList(委托A,委托B,委托C,委托D,委托E);
    
    委托A : 即将开始请求服务器时的委托 Action
    委托B : 第一个资源开始下载时的委托 Action<float,int> <首个下载资源长度,总的下载.asset个数>
    委托C : 单个asset包下载进度更新的委托 Action<string, HTTPRequest, float, float> <包名,下载request对象,当前已下载长度,总长度>
    委托D : 当一个资源下载完成后的委托  Action<int,int> <当前下载完成个数,还需要下载个数>
    委托E : 所有资源下载完成后的委托 Action
    
    加载调用
    GameObject gobj = AssetBundleManager.Instance.LoadAssetWithPath(asset包名,asset个体名,是否Unload资源,是否Instantiate实例化);
    
    asset包名 : "role2s"  即个体所在的文件名
    asset个体名 : "role2_003" 个体的名称
    是否Unload资源 : true 
    是否Instantiate实例化 : false
    
    

    相关文章

      网友评论

          本文标题:[个人框架 C_Framework] 快速打包AssetBund

          本文链接:https://www.haomeiwen.com/subject/cygqxqtx.html