打包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_unity和common_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注意事项:
- 引用了litjson库,请自行百度下载,或者替换成别的库都OK
- 引用了BestHttp的Http请求库,个人觉得比unity自带的www和UnityWebRequest好用很多
- 继承自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
网友评论