从AssetBundleConfig中获取版本号
/// <summary>
/// 获取版本号
/// </summary>
/// <returns></returns>
public string GetVersion()
{
XElement root = xDoc.Root;
XElement assetBundleNode = root.Element("AssetBundle");
XAttribute attribute = assetBundleNode.Attribute("ResourceVersion");
return attribute.Value;
}
升级版本号
/// <summary>
/// 升级版本号
/// </summary>
public void UpdateVersion()
{
XElement root = xDoc.Root;
XElement assetBundleNode = root.Element("AssetBundle");
XAttribute attribute = assetBundleNode.Attribute("ResourceVersion");
string version = attribute.Value;
string[] arr = version.Split('.');
int shortVersion = int.Parse(arr[2]);
version = string.Format("{0}.{1}.{2}", arr[0], arr[1], ++shortVersion);
attribute.SetValue(version);
xDoc.Save(m_Path);
}
升级资源版本号
绘制UI
void OnGUI()
{
if (m_List == null) return;
#region 按钮行
GUILayout.BeginHorizontal("box");//开启一个横向列
//选择平台
int selectBuildTargetIndex = EditorGUILayout.Popup(buildTargetIndex, arrBuildTarget, GUILayout.Width(100));
if (selectBuildTargetIndex != buildTargetIndex)
{
buildTargetIndex = selectBuildTargetIndex;
EditorApplication.delayCall = OnSelectTargetCallBack;
}
if (GUILayout.Button("保存设置", GUILayout.Width(200)))
{
EditorApplication.delayCall = OnSaveSettingCallBack;
}
if (GUILayout.Button("清空设置", GUILayout.Width(200)))
{
EditorApplication.delayCall = OnClearSettingCallBack;
}
if (GUILayout.Button("清空 AssetBundle", GUILayout.Width(200)))
{
EditorApplication.delayCall = OnClearAssetBundleCallBack;
}
if (GUILayout.Button("AssetBundle 打包", GUILayout.Width(200)))
{
EditorApplication.delayCall = OnAssetBundleCallBack;
}
if (GUILayout.Button("升级资源版本号(" + dal.GetVersion() + ")", GUILayout.Width(200)))
{
EditorApplication.delayCall = OnUpdateVersionCallBack;
}
EditorGUILayout.Space();
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal("box");//开启一个横向列
if (GUILayout.Button("生成AssetInfo.bytes", GUILayout.Width(200)))
{
EditorApplication.delayCall = OnCreateDependenciesFile;
}
if (GUILayout.Button("生成版本文件", GUILayout.Width(200)))
{
EditorApplication.delayCall = OnCreateVersionFileCallBack;
}
EditorGUILayout.Space();
GUILayout.EndHorizontal();
#endregion
#region 文字说明行
GUILayout.BeginHorizontal("box");
GUILayout.Label("资源包名称");
GUILayout.Label("标记", GUILayout.Width(100));
GUILayout.Label("是否文件夹", GUILayout.Width(200));
GUILayout.Label("是否初始资源", GUILayout.Width(200));
GUILayout.Label("是否加密", GUILayout.Width(220));
GUILayout.EndHorizontal();
#endregion
#region 显示的资源包信息列表
GUILayout.BeginVertical();
pos = EditorGUILayout.BeginScrollView(pos);//生成一个滚动条
for (int i = 0; i < m_List.Count; i++)
{
AssetBundleEntity entity = m_List[i];
GUILayout.BeginHorizontal("box");
m_Dic[entity.Key] = GUILayout.Toggle(m_Dic[entity.Key], "", GUILayout.Width(20));
GUILayout.Label(entity.Name);
GUILayout.Label(entity.Tag, GUILayout.Width(100));
GUILayout.Label(entity.IsFolder.ToString(), GUILayout.Width(200));
GUILayout.Label(entity.IsFirstData.ToString(), GUILayout.Width(200));
GUILayout.Label(entity.IsEncrypt.ToString(), GUILayout.Width(200));
GUILayout.EndHorizontal();
foreach (string path in entity.PathList)
{
GUILayout.BeginHorizontal("box");
GUILayout.Space(40);
GUILayout.Label(path);
GUILayout.EndHorizontal();
}
}
EditorGUILayout.EndScrollView();
GUILayout.EndVertical();
#endregion
}
升级版本号
/// <summary>
/// 升级版本号
/// </summary>
private void OnUpdateVersionCallBack()
{
dal.UpdateVersion();
}
升级
/// <summary>
/// 升级版本号
/// </summary>
public void UpdateVersion()
{
XElement root = xDoc.Root;
XElement assetBundleNode = root.Element("AssetBundle");
XAttribute attribute = assetBundleNode.Attribute("ResourceVersion");
string version = attribute.Value;
string[] arr = version.Split('.');
int shortVersion = int.Parse(arr[2]);
version = string.Format("{0}.{1}.{2}", arr[0], arr[1], ++shortVersion);
attribute.SetValue(version);
xDoc.Save(m_Path);
}
using System.Collections.Generic;
using System.Xml.Linq;
/// <summary>
/// AssetBundle XML数据解析类
/// </summary>
public class AssetBundleDAL
{
/// <summary>
/// XML路径
/// </summary>
private string m_Path;
/// <summary>
/// 返回的数据集合
/// </summary>
private List<AssetBundleEntity> m_List = null;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="path"></param>
public AssetBundleDAL(string path)
{
m_Path = path;
m_List = new List<AssetBundleEntity>();
}
private XDocument xDoc;
/// <summary>
/// 获取版本号
/// </summary>
/// <returns></returns>
public string GetVersion()
{
XElement root = xDoc.Root;
XElement assetBundleNode = root.Element("AssetBundle");
XAttribute attribute = assetBundleNode.Attribute("ResourceVersion");
return attribute.Value;
}
/// <summary>
/// 升级版本号
/// </summary>
public void UpdateVersion()
{
XElement root = xDoc.Root;
XElement assetBundleNode = root.Element("AssetBundle");
XAttribute attribute = assetBundleNode.Attribute("ResourceVersion");
string version = attribute.Value;
string[] arr = version.Split('.');
int shortVersion = int.Parse(arr[2]);
version = string.Format("{0}.{1}.{2}", arr[0], arr[1], ++shortVersion);
attribute.SetValue(version);
xDoc.Save(m_Path);
}
/// <summary>
/// 返回xml数据
/// </summary>
/// <returns></returns>
public List<AssetBundleEntity> GetList()
{
m_List.Clear();
//读取xml 把数据添加到m_List里边
xDoc = XDocument.Load(m_Path);
XElement root = xDoc.Root;
XElement assetBundleNode = root.Element("AssetBundle");
IEnumerable<XElement> lst = assetBundleNode.Elements("Item");
int index = 0;
foreach (XElement item in lst)
{
AssetBundleEntity entity = new AssetBundleEntity();
entity.Key = "key" + ++index;
entity.Name = item.Attribute("Name").Value;
entity.Tag = item.Attribute("Tag").Value;
entity.IsFolder = item.Attribute("IsFolder").Value.Equals("True", System.StringComparison.CurrentCultureIgnoreCase);
entity.IsFirstData = item.Attribute("IsFirstData").Value.Equals("True", System.StringComparison.CurrentCultureIgnoreCase);
entity.IsEncrypt = item.Attribute("IsEncrypt").Value.Equals("True", System.StringComparison.CurrentCultureIgnoreCase);
IEnumerable<XElement> pathList = item.Elements("Path");
foreach (XElement path in pathList)
{
entity.PathList.Add(path.Attribute("Value").Value);
}
m_List.Add(entity);
}
return m_List;
}
}
打包
#region OnAssetBundleCallBack AssetBundle打包 按钮回调
/// <summary>
/// AssetBundle打包按钮回调
/// </summary>
private void OnAssetBundleCallBack()
{
//如果存在同名的文件,先删除掉
AssetBundleEncrypt(true);
//AssetBundle打包
//打包的文件设置到版本号下面
string toPath = Application.dataPath + "/../AssetBundles/" + dal.GetVersion() + "/" + arrBuildTarget[buildTargetIndex];
if (!Directory.Exists(toPath)) Directory.CreateDirectory(toPath);//如果路径不存在 创建路径
BuildPipeline.BuildAssetBundles(toPath, BuildAssetBundleOptions.ChunkBasedCompression, target);
Debug.Log("资源打包完毕 打包路径==" + toPath);
//AssetBundle加密
AssetBundleEncrypt();
//生成依赖文件
OnCreateDependenciesFile();
//生成版本文件
OnCreateVersionFileCallBack();
Debug.Log("AssetBundle 打包并加密完毕!");
}
生成版本文件
#region OnCreateVersionFileCallBack 生成版本文件按钮回调
/// <summary>
/// 生成版本文件
/// </summary>
private void OnCreateVersionFileCallBack()
{
//1.获取版本文件路径
string path = Application.dataPath + "/../AssetBundles/" + dal.GetVersion() + "/" + arrBuildTarget[buildTargetIndex];
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string strVersionFilePath = path + "/VersionFile.txt";
//2.如果之前有创建过版本文件 则删除之前的
IOUtil.DeleteFile(strVersionFilePath);
//3.拿到文件夹以及子目录下所有文件
StringBuilder sbContent = new StringBuilder();//版本文件内的字符串
DirectoryInfo directory = new DirectoryInfo(path);//根据路径获取到文件夹
FileInfo[] arrFiles = directory.GetFiles("*", SearchOption.AllDirectories);
//文件的第一行添加版本号
sbContent.AppendLine(dal.GetVersion());
for (int i = 0; i < arrFiles.Length; i++)//遍历所有文件
{
FileInfo file = arrFiles[i];
if (file.Extension == ".manifest") continue;
string fullName = file.FullName;//获取绝对路径; 包含路径,文件名.扩展名
//转换为相对路径
string name = fullName.Substring(fullName.IndexOf(arrBuildTarget[buildTargetIndex]) + arrBuildTarget[buildTargetIndex].Length + 1);
//获取文件的MD5
string md5 = EncryptUtil.GetFileMD5(fullName);
if (md5 == null) continue;
//获取文件大小
string size = file.Length.ToString();
bool isFirstData = false;//是否初始数据
bool isEncrypt = false;//是否加密
//4.每个文件和XML中的路径进行比对
bool isBreak = false;
for (int j = 0; j < m_List.Count; j++)//遍历xml中所有资源包项Entity
{
foreach (string xmlPath in m_List[j].PathList)
{
string tempPath = xmlPath;
if (xmlPath.IndexOf(".") != -1)
{
tempPath = xmlPath.Substring(0, xmlPath.IndexOf("."));
}
name = name.Replace("\\", "/");
if (name.IndexOf(tempPath, StringComparison.CurrentCultureIgnoreCase) != -1)
{
isFirstData = m_List[j].IsFirstData;
isEncrypt = m_List[j].IsEncrypt;
isBreak = true;
break;
}
}
if (isBreak) break;
}
string strLine = string.Format("{0}|{1}|{2}|{3}|{4}", name, md5, size, isFirstData ? 1 : 0, isEncrypt ? 1 : 0);
sbContent.AppendLine(strLine);
}
Debug.Log(strVersionFilePath);
Debug.Log(sbContent.ToString());
//创建开发者参考的.txt版本文件
IOUtil.CreateTextFile(strVersionFilePath, sbContent.ToString());
//创建客户端真正使用的.bytes版本文件
MMO_MemoryStream ms = new MMO_MemoryStream();
string str = sbContent.ToString().Trim();
string[] arr = str.Split('\n');
int len = arr.Length;
ms.WriteInt(len);//长度
for (int i = 0; i < len; i++)
{
if (i == 0)
{
ms.WriteUTF8String(arr[i]);
}
else
{
string[] arrInner = arr[i].Split('|');
ms.WriteUTF8String(arrInner[0]);
ms.WriteUTF8String(arrInner[1]);
ms.WriteULong(ulong.Parse(arrInner[2]));
ms.WriteByte(byte.Parse(arrInner[3]));
ms.WriteByte(byte.Parse(arrInner[4]));
}
}
string filePath = path + "/VersionFile.bytes"; //版本文件路径
byte[] buffer = ms.ToArray();
buffer = ZlibHelper.CompressBytes(buffer);
FileStream fs = new FileStream(filePath, FileMode.Create);
fs.Write(buffer, 0, buffer.Length);
fs.Close();
Debug.Log("创建版本文件成功");
}
#endregion