using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using System.Text.RegularExpressions;
public class AssetBundleBuilder : EditorWindow
{
static string m_Version = "1.1.1";
static string m_ResourcesPath = "Assets/Resources/";
static BuildTarget m_BuildTarget = BuildTarget.StandaloneWindows64;
static List<string> m_IgnoreSuffixs = new List<string> { ".cs", ".shader", ".unity" };
static string m_PlatformPath;
static string m_ManifestPath;
static string m_AssetBundlePath;
[MenuItem("Tools/AssetBundleBuilder")]
static void Init()
{
var window = (AssetBundleBuilder)GetWindow(typeof(AssetBundleBuilder));
window.Show();
}
void OnGUI()
{
GUILayout.Label("AssetBundleBuilder", EditorStyles.boldLabel);
EditorGUILayout.LabelField("打包平台", AssetBundleUtil.GetPlatform());
m_Version = EditorGUILayout.TextField("版本号", m_Version);
m_BuildTarget = (BuildTarget)EditorGUILayout.EnumPopup("目标平台", m_BuildTarget);
m_PlatformPath = "D:/PackProject/AssetBundle/" + m_BuildTarget.ToString();
m_ManifestPath = m_PlatformPath + "/manifest";
m_AssetBundlePath = m_PlatformPath + "/" + m_Version;
EditorGUILayout.LabelField("保存路径: ", m_AssetBundlePath);
if (GUILayout.Button("Clear Manifest Folder"))
ClearStorageFolder();
if (GUILayout.Button("Clear All AssetBundleNames"))
ClearAssetBundleName();
if (GUILayout.Button("Build"))
Build();
}
static void Build()
{
ClearAssetBundleName();
SetAssetBundleName();
CreateAssetBundle();
MoveAssetBundle();
BuildZipFile();
}
static void MoveAssetBundle()
{
var info = new DirectoryInfo(m_AssetBundlePath);
if (info.Exists)
info.Delete(true);
info.Create();
var index = 0;
var assetFolder = new DirectoryInfo(m_ManifestPath);
var allFiles = assetFolder.GetFiles("*", SearchOption.AllDirectories);
foreach (var file in allFiles)
{
if (file.FullName.Contains(".manifest"))
continue;
var name = file.FullName.Replace("\\", "/");
name = name.Replace(m_ManifestPath, "");
var t = m_AssetBundlePath + name;
var folder = t.Remove(t.LastIndexOf("/"));
var tempfolder = new DirectoryInfo(folder);
if (! tempfolder.Exists)
tempfolder.Create();
file.MoveTo(t);
EditorUtility.DisplayProgressBar("移动文件。。", name, (float)index / allFiles.Length);
}
EditorUtility.ClearProgressBar();
}
static void ClearStorageFolder()
{
var dirInfo = new DirectoryInfo(m_ManifestPath);
if (dirInfo.Exists)
dirInfo.Delete(true);
}
static void BuildZipFile()
{
var infos = new DirectoryInfo(m_AssetBundlePath);
var compressTotal = infos.GetFiles("*.*", SearchOption.AllDirectories).Length;
if (compressTotal <= 0)
return;
var folders = new string[] { m_AssetBundlePath };
var outputZip = m_PlatformPath + "/res_all_" + m_Version + ".zip";
ZipUtility.Zip(folders, outputZip, "aiteachu", new AssetBundleZipCallBack(compressTotal));
EditorUtility.ClearProgressBar();
}
static void ClearAssetBundleName()
{
var names = AssetDatabase.GetAllAssetBundleNames();
var index = 0;
foreach (var name in names)
{
index++;
var progress = (float)index / names.Length;
EditorUtility.DisplayProgressBar("清除AssetBundle标记", name, progress);
AssetDatabase.RemoveAssetBundleName(name, true);
}
EditorUtility.ClearProgressBar();
}
static void SetAssetBundleName()
{
//SetAssetName(m_ResourcesPath, ".json", false);
SetAssetName(m_ResourcesPath, ".playable", false);
//SetAssetName(m_ResourcesPath + "UIImage/", ".png", false);
//SetAssetName(m_ResourcesPath + "UIImage/", ".jpg", false);
//SetAssetName(m_ResourcesPath, ".mat", false);
//SetAssetName(m_ResourcesPath, ".prefab", false);
//SetAssetName(m_ResourcesPath, ".controller", false);
//SetAssetName(m_ResourcesPath, ".unity", false);
}
static void CreateAssetBundle()
{
var info = new DirectoryInfo(m_ManifestPath);
if (! info.Exists)
info.Create();
var option = BuildAssetBundleOptions.ChunkBasedCompression;
BuildPipeline.BuildAssetBundles(m_ManifestPath, option, m_BuildTarget);
}
static void SetAssetName(string resourcesPath, string filter, bool excludeDependences)
{
var paths = GetPaths(resourcesPath, filter);
var index = 0;
foreach (var path in paths)
{
index++;
var progress = (float)index / paths.Count;
if (!CheckPath(path))
{
Debug.LogError("path has error : " + path);
continue;
}
var tempPath = path.Replace("\\", "/");
var name = tempPath.Remove(tempPath.LastIndexOf('.'));
SetName(tempPath, name);
if (excludeDependences)
SetDenpendencesName(tempPath);
EditorUtility.DisplayProgressBar("SetName...", path, progress);
}
EditorUtility.ClearProgressBar();
}
// 去除掉不符合命名规则的文件 文件名只包含数字,大小写字符,下滑线 空格 & . -
public static bool CheckPath(string path)
{
var name = Path.GetFileNameWithoutExtension(path);
var rex = new Regex(@"^[0-9A-Za-z_&][0-9A-Za-z_\s&.-]*$");
var ma = rex.Match(name);
return ma.Success;
}
static void SetDenpendencesName(string target)
{
var denpendences = AssetDatabase.GetDependencies(target);
foreach (var dependencePath in denpendences)
{
var extension = Path.GetExtension(dependencePath);
if (m_IgnoreSuffixs.Contains(extension))
continue;
var name = dependencePath.Remove(dependencePath.LastIndexOf('.'));
SetName(dependencePath, name);
}
}
static void SetName(string path, string name)
{
var import = AssetImporter.GetAtPath(path);
if (string.IsNullOrEmpty(import.assetBundleName))
{
name = name.Replace(" ", "");
name = name.Replace("-", "_");
import.SetAssetBundleNameAndVariant(name, null);
}
}
static List<string> GetPaths(string dirPath, string suffix)
{
var ls = new List<string>();
foreach (string path in Directory.GetFiles(dirPath))
{
if (Path.GetExtension(path) == suffix)
ls.Add(path.Substring(path.IndexOf("Assets")));
}
var dirs = Directory.GetDirectories(dirPath);
if (dirs.Length > 0)
{
foreach (string path in dirs)
ls.AddRange(GetPaths(path, suffix));
}
return ls;
}
class AssetBundleZipCallBack : ZipUtility.ZipCallback
{
int m_Index;
int m_Total;
public AssetBundleZipCallBack(int total)
{
m_Total = total;
}
// 压缩单个文件或文件夹后执行的回调
public override void OnPostZip(ZipEntry entry)
{
m_Index++;
var progress = (float)m_Index / m_Total;
EditorUtility.DisplayProgressBar("压缩文件夹", entry.Name, progress);
}
public override void OnFinished(bool result)
{
m_Index = 0;
m_Total = 0;
if(result)
Debug.Log("======压缩完成=========");
else
Debug.Log("======压缩失败=========");
}
}
}