欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity AssetBundle打包

程序员文章站 2022-04-03 15:36:36
...
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;

public class AssetBundleBuilder : Editor
{
    private static List<AssetBundleBuild> builds = new List<AssetBundleBuild>();

    private static Dictionary<string, List<string>> abNames = new Dictionary<string, List<string>>();

    private static List<string> filterList = new List<string> { ".cs", ".meta", ".tpsheet" };

    /// <summary>
    /// 通过自动寻找依赖打包
    /// </summary>
    /// <param name="sourcePath"></param>
    /// <param name="outputPath"></param>
    public static void BuildAssetBundle(string sourcePath, string outputPath)
    {
        builds.Clear();
        abNames.Clear();

        ClearAssetBundlesName();
        
        Pack(sourcePath);

        if (!Directory.Exists(outputPath))
        {
            Directory.CreateDirectory(outputPath);
        }

        BuildPipeline.BuildAssetBundles(outputPath,
            builds.ToArray(),
            BuildAssetBundleOptions.UncompressedAssetBundle,
            EditorUserBuildSettings.activeBuildTarget);

        AssetDatabase.Refresh();
        
        builds.Clear();
        abNames.Clear();
        Debug.Log("打包完成");
    }

    /// <summary>
    /// 通过文件夹打包
    /// </summary>
    /// <param name="sourcePath"></param>
    /// <param name="outputPath"></param>
    public static void BuildAssetBundleByDirectory(string outputPath, params string[] sourcePaths)
    {
        builds.Clear();
        abNames.Clear();

        ClearAssetBundlesName();

        fileWithDirectory(sourcePaths);
        
        if (!Directory.Exists(outputPath))
        {
            Directory.CreateDirectory(outputPath);
        }

        BuildPipeline.BuildAssetBundles(outputPath,
            builds.ToArray(),
            BuildAssetBundleOptions.ChunkBasedCompression,
            EditorUserBuildSettings.activeBuildTarget);

        AssetDatabase.Refresh();


        foreach (string key in abNames.Keys)
        {
            string str = key;
            List<string> list = abNames[key];

            if (list.Count < 2) continue;

            foreach (var item in list)
            {
                str = str + "\n" + item;
            }
            Debug.LogWarning(str + "\n");
        }

        builds.Clear();
        abNames.Clear();
        Debug.Log("打包完成");
    }


    /// <summary>  
    /// 清除之前设置过的AssetBundleName,避免产生不必要的资源也打包  
    /// 之前说过,只要设置了AssetBundleName的,都会进行打包,不论在什么目录下  
    /// </summary>  
    static void ClearAssetBundlesName()//----------------待优化
    {
        int length = AssetDatabase.GetAllAssetBundleNames().Length;
        Debug.Log(length);
        string[] oldAssetBundleNames = new string[length];
        for (int i = 0; i < length; i++)
        {
            oldAssetBundleNames[i] = AssetDatabase.GetAllAssetBundleNames()[i];
        }

        for (int j = 0; j < oldAssetBundleNames.Length; j++)
        {
            AssetDatabase.RemoveAssetBundleName(oldAssetBundleNames[j], true);
        }
        length = AssetDatabase.GetAllAssetBundleNames().Length;
        Debug.Log(length);
    }

    static void Pack(string source)
    {
        DirectoryInfo folder = new DirectoryInfo(source);
        FileSystemInfo[] files = folder.GetFileSystemInfos();
        int length = files.Length;
        for (int i = 0; i < length; i++)
        {
            if (files[i] is DirectoryInfo)
            {
                Pack(files[i].FullName);
            }
            else
            {
                if (!files[i].Name.EndsWith(".meta") && !files[i].Name.EndsWith(".tpsheet"))
                {
                    fileWithDepends(files[i].FullName);
                }
            }
        }
    }
     /// <summary>
     /// 自动寻找依赖 打包AB
     /// </summary>
     /// <param name="source"></param>
    static void fileWithDepends(string source)
    {
        Debug.Log("file source: " + source);
        string _source = Replace(source);
        string _assetPath = "Assets" + _source.Substring(Application.dataPath.Length);
        Debug.Log("assetPath :" + _assetPath);
        string sourceName = string.Format("{0}.data", Path.GetFileNameWithoutExtension(_source));

        //自动获取依赖项并给其资源设置AssetBundleName
        string[] dps = AssetDatabase.GetDependencies(_assetPath);
        List<string> assetNames = new List<string>();
        foreach (string dp in dps)
        {
            Debug.Log("dp :" + dp);
            if (dp.EndsWith(".cs"))
                continue;
            if (abNames.ContainsKey(dp))
            {
                abNames[dp].Add(sourceName);
                continue;
            }
            else
            {
                abNames[dp] = new List<string>();
                abNames[dp].Add(sourceName);
            }
            assetNames.Add(dp);
        }

        AssetBundleBuild build = new AssetBundleBuild();
        build.assetBundleName = sourceName;
        build.assetNames = assetNames.ToArray();
        builds.Add(build);
    }

    /// <summary>
    /// 按目录打包
    /// </summary>
    /// <param name="source"></param>
    static void fileWithDirectory(params string[] sources)
    {
        for (int i = 0; i < sources.Length; i++)
        {
            string source = sources[i];

            source = Replace(source);
            DirectoryInfo folder = new DirectoryInfo(source);
            DirectoryInfo[] dires = folder.GetDirectories();

            foreach (DirectoryInfo d in dires)
            {
                Debug.Log("file source: " + d.FullName);

                string assetBundleName = d.Name + ".data";
                assetBundleName = assetBundleName.ToLower();
                List<string> assetNames = new List<string>();

                FileInfo[] files = d.GetFiles();
                foreach (FileInfo file in files)
                {
                    if (filterList.Contains(file.Extension))
                        continue;

                    string assetName = file.FullName.Substring(Application.dataPath.Length - 6);
                    assetName = Replace(assetName);

                    Debug.Log("----- dp :" + assetName);

                    if (abNames.ContainsKey(assetName))
                    {
                        abNames[assetName].Add(assetBundleName);
                        continue;
                    }
                    else
                    {
                        abNames[assetName] = new List<string>();
                        abNames[assetName].Add(assetBundleName);
                        assetNames.Add(assetName);
                    }
                }

                AssetBundleBuild build = new AssetBundleBuild();
                build.assetBundleName = assetBundleName;
                build.assetNames = assetNames.ToArray();
                builds.Add(build);
            }
        }
    }

    static string Replace(string s)
    {
        return s.Replace("\\", "/");
    }


}

public class Platform
{
    public static string GetPlatformFolder(BuildTarget target)
    {
        switch (target)
        {
            case BuildTarget.Android:
                return "Android";
            case BuildTarget.iOS:
                return "IOS";
            case BuildTarget.StandaloneWindows:
            case BuildTarget.StandaloneWindows64:
                return "Windows";
            case BuildTarget.StandaloneOSX:
                return "OSX";
            default:
                return null;
        }
    }
}