这个资源打包工具写的也是……极简的……
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Collections.Generic;
using System;
/// <summary>
/// 资源打包工具窗口
/// </summary>
public class ResBuildWindow : EditorWindow
{
static ResBuildWindow buildWindow;
/// <summary>
/// 资源平台列表
/// </summary>
static List<string> platformStrings = new List<string>();
/// <summary>
/// 当前资源平台索引
/// </summary>
static int nowPlatformIndex = 0;
/// <summary>
/// 是否处于焦点状态
/// </summary>
static bool isFocused = false;
/// <summary>
/// 数据是否加载
/// </summary>
static bool isLoadData = false;
/// <summary>
/// 预制体路径
/// </summary>
static string prefabPath;
/// <summary>
/// ab文件的根目录
/// </summary>
static string abPathRoot;
/// <summary>
/// AB文件路径
/// </summary>
static string abPath;
[MenuItem("工具/资源打包工具")]
static void Init()
{
buildWindow = (ResBuildWindow)EditorWindow.GetWindow(typeof(ResBuildWindow), false, "打包工具", true);
buildWindow.Show();
LoadData();
}
/// <summary>
/// 获得焦点
/// </summary>
private void OnFocus()
{
isFocused = true;
if (!isLoadData)
{
LoadData();
}
}
/// <summary>
/// 丢失焦点
/// </summary>
private void OnLostFocus()
{
isFocused = false;
isLoadData = false;
}
/// <summary>
/// 加载数据
/// </summary>
static void LoadData()
{
prefabPath = Application.dataPath + "/Resources/UIPrefabs";
abPathRoot = Application.persistentDataPath + "/AB/";
if (Directory.Exists(abPathRoot))
{
Directory.CreateDirectory(abPathRoot);
}
platformStrings.Clear();
platformStrings.Add(BuildTarget.Android.ToString());
platformStrings.Add(BuildTarget.iOS.ToString());
platformStrings.Add(BuildTarget.StandaloneWindows.ToString());
platformStrings.Add(BuildTarget.WebGL.ToString());
//platformStrings.Add(BuildTarget.StandaloneOSXUniversal.ToString());
isLoadData = true;
}
void OnGUI()
{
if (!isFocused)
{
return;
}
EditorGUILayout.Space();
if (GUILayout.Button("设置资源的AB名"))
{
SetAllAbNames();
}
EditorGUILayout.Space();
if (GUILayout.Button("打印所有的AB包名字"))
{
PrintABsNames();
}
EditorGUILayout.Space();
if (GUILayout.Button("清除所有AB包的名字"))
{
ClearABsName();
}
EditorGUILayout.Space();
EditorGUILayout.Space();
GUILayout.Label("选择打包平台");
nowPlatformIndex = GUILayout.Toolbar(nowPlatformIndex, platformStrings.ToArray());
EditorGUILayout.Space();
if (GUILayout.Button("打包所选平台资源"))
{
EditorUtility.DisplayProgressBar("打包所选平台资源", "打包所选平台资源", 0);
BuildTarget bt = (BuildTarget)Enum.Parse(typeof(BuildTarget), platformStrings[nowPlatformIndex]);
string abPath = abPathRoot + GetPlatformName(bt) + "/";
if (!Directory.Exists(abPath))
{
Directory.CreateDirectory(abPath);
}
DirectoryInfo di = new DirectoryInfo(abPath);
foreach (FileInfo fi in di.GetFiles())
{
fi.Delete();
}
//BuildAssetBundleOptions
BuildPipeline.BuildAssetBundles(abPath, BuildAssetBundleOptions.None, bt);
CreateABMD5List.Execute(abPath);
EditorUtility.ClearProgressBar();
}
EditorGUILayout.Space();
if (GUILayout.Button("打包所有平台资源"))
{
EditorUtility.DisplayProgressBar("打包所有平台资源", "打包所有平台资源", 0);
for (int i = 0; i < platformStrings.Count; i++)
{
BuildTarget bt = (BuildTarget)Enum.Parse(typeof(BuildTarget), platformStrings[i]);
string abPath = abPathRoot + GetPlatformName(bt) + "/";
if (!Directory.Exists(abPath))
{
Directory.CreateDirectory(abPath);
}
DirectoryInfo di = new DirectoryInfo(abPath);
foreach (FileInfo fi in di.GetFiles())
{
fi.Delete();
}
BuildPipeline.BuildAssetBundles(abPath, BuildAssetBundleOptions.None, bt);
CreateABMD5List.Execute(abPath);
}
EditorUtility.ClearProgressBar();
}
EditorGUILayout.Space();
}
/// <summary>
/// 设置资源的AB名,这里可以处理资源文件的依赖关系,比如可以把一个文件的图片打成一个ab包,各种别的选择……
/// </summary>
void SetAllAbNames()
{
EditorUtility.DisplayProgressBar("设置预制的AB名", "设置预制的AB名", 0);
DirectoryInfo folder = new DirectoryInfo(prefabPath);
foreach (FileInfo file in folder.GetFiles("*.prefab"))
{
AssetImporter importer = AssetImporter.GetAtPath("Assets/Resources/UIPrefabs/" + file.Name);
//设置ab名
importer.assetBundleName = Util.GetFileRealName(file.Name.ToLower());
//设置ab文件的后缀
importer.assetBundleVariant = "t";
}
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
}
/// <summary>
/// 打印所有的AB包名字
/// </summary>
void PrintABsNames()
{
EditorUtility.DisplayProgressBar("打印所有的AB包名字", "打印所有的AB包名字", 0);
//获取所有设置的AssetBundle
string[] names = AssetDatabase.GetAllAssetBundleNames();
foreach (string name in names)
{
Debug.Log("AB名: " + name);
}
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
}
/// <summary>
/// 清除所有AB包的名字
/// </summary>
void ClearABsName()
{
EditorUtility.DisplayProgressBar("清除", "清除所有AB包的名字", 0);
string[] ABsNames = AssetDatabase.GetAllAssetBundleNames();
for (int j = 0; j < ABsNames.Length; j++)
{
AssetDatabase.RemoveAssetBundleName(ABsNames[j], true);
}
//刷新资源
AssetDatabase.Refresh();
EditorUtility.ClearProgressBar();
}
/// <summary>
/// 获取平台名
/// </summary>
/// <param name="bt"></param>
/// <returns></returns>
private static string GetPlatformName(BuildTarget bt)
{
switch (bt)
{
case BuildTarget.Android:
case BuildTarget.iOS:
return bt.ToString();
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
return "Windows";
case BuildTarget.WebGL:
return "WebGL";
case BuildTarget.StandaloneOSXIntel:
case BuildTarget.StandaloneOSXIntel64:
case BuildTarget.StandaloneOSXUniversal:
return "OSX";
default:
Debug.LogError("不支持的打包渠道");
return "";
}
}
}
using UnityEditor;
using System.IO;
using System.Xml;
using System.Collections.Generic;
using System;
using UnityEngine;
/// <summary>
/// 创建AB文件的列表xml
/// </summary>
public class CreateABMD5List
{
public static void Execute(BuildTarget target)
{
Execute(target);
AssetDatabase.Refresh();
}
public static void Execute(string path)
{
VersionInfo versionInfo = new VersionInfo();
versionInfo.content = new List<UpdateContent>();
DirectoryInfo folder = new DirectoryInfo(path);
foreach (FileInfo file in folder.GetFiles())
{
//if (file.Name.Contains("Android")|| file.Name.Contains("iOS")|| file.Name.Contains("Win"))
//{
// File.Delete(file.FullName);
// continue;
//}
//if (file.Name.Contains(".manifest"))
//{
// File.Delete(file.FullName);
// continue;
//}
if (file.Name.Contains(".DS_Store") || file.Name.Contains(".meta") || file.Name.Contains(".txt"))
{
continue;
}
if (!Path.GetFileName(file.FullName).Contains("."))
{
file.MoveTo(file.FullName + ".t");
}
UpdateContent ui = new UpdateContent();
ui.name = Path.GetFileName(file.FullName);
ui.md5 = Util.GetFileMD5(file.FullName);
versionInfo.content.Add(ui);
}
// 删除前一版的old数据
if (File.Exists(path + "/VersionMD5-old.txt"))
{
File.Delete(path + "/VersionMD5-old.txt");
}
// 如果之前的版本存在,则将其名字改为VersionMD5-old.txt
if (File.Exists(path + "/VersionMD5.txt"))
{
File.Move(path + "/VersionMD5.txt", path + "/VersionMD5-old.txt");
}
// 读取旧版本的MD5
VersionInfo oldVersionInfo = ReadMD5File(path + "/VersionMD5-old.txt");
if (File.Exists(path + "/VersionMD5-old.txt"))
{
File.Delete(path + "/VersionMD5-old.txt");
}
XmlDocument XmlDoc = new XmlDocument();
XmlElement XmlRoot = XmlDoc.CreateElement("Files");
XmlDoc.AppendChild(XmlRoot);
XmlElement ver = XmlDoc.CreateElement("Version");
XmlRoot.AppendChild(ver);
if (oldVersionInfo.version > 0)
{
ver.SetAttribute("code", oldVersionInfo.version + 1 + "");
}
else
{
ver.SetAttribute("code", 1 + "");
}
for (int i = 0; i < versionInfo.content.Count; i++)
{
XmlElement xmlElem = XmlDoc.CreateElement("File");
XmlRoot.AppendChild(xmlElem);
xmlElem.SetAttribute("name", versionInfo.content[i].name);
xmlElem.SetAttribute("md5", versionInfo.content[i].md5);
}
//oldVersionInfo中有,而versionInfo中没有的信息,手动添加到versionInfo
foreach (UpdateContent oui in oldVersionInfo.content)
{
if (!versionInfo.content.Contains(oui))
{
versionInfo.content.Add(oui);
}
}
XmlDoc.Save(path + "/VersionMD5.txt");
XmlDoc = null;
}
/// <summary>
/// 读取文件md5列表
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static VersionInfo ReadMD5File(string fileName)
{
VersionInfo versionInfo = new VersionInfo();
versionInfo.content = new List<UpdateContent>();
versionInfo.version = 0;
try
{
// 如果文件不存在,则直接返回
if (File.Exists(fileName) == false)
{
return versionInfo;
}
XmlDocument XmlDoc = new XmlDocument();
XmlDoc.Load(fileName);
XmlElement XmlRoot = XmlDoc.DocumentElement;
foreach (XmlNode node in XmlRoot.ChildNodes)
{
//Debug.Log("node.Name:" + node.Name);
if (node.Name == "File")
{
if ((node is XmlElement) == false)
{
continue;
}
UpdateContent ui = new UpdateContent();
ui.name = (node as XmlElement).GetAttribute("name");
ui.md5 = (node as XmlElement).GetAttribute("md5");
versionInfo.content.Add(ui);
}
else
{
versionInfo.version = Convert.ToInt32((node as XmlElement).GetAttribute("code"));
}
}
XmlRoot = null;
XmlDoc = null;
}
catch (Exception e)
{
Debug.LogError(e.ToString());
}
return versionInfo;
}
/// <summary>
/// 更新的版本信息
/// </summary>
public struct VersionInfo
{
/// <summary>
/// 版本号
/// </summary>
public int version;
/// <summary>
/// 更新的内容
/// </summary>
public List<UpdateContent> content;
}
/// <summary>
/// 更新内容信息
/// </summary>
public struct UpdateContent
{
/// <summary>
/// 名称
/// </summary>
public string name;
/// <summary>
/// md5
/// </summary>
public string md5;
}
}