unity assetbundle builder


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("======压缩失败=========");
        }
    }
}

 

 

 

posted @ 2020-04-29 16:30  liuchong9123  阅读(371)  评论(0编辑  收藏  举报