美文网首页
[个人框架 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