Unity3d中自动生成asset bundle name

来源:互联网 发布:淘宝一元抢 编辑:程序博客网 时间:2024/05/02 08:47
引言:
在unity3d的实际项目开发中,由于资源的增删改频繁,手动设置asset bundle name是一项繁琐且容易出错的工作,所以衍生出了开发自动化工具的需求。
工作原理:
以文件夹为目标,设置asset bundle name,在目标文件夹内的文件都会打进同一个asset bundle。
实现原理:
通过遍历Asset路径下的所有文件夹,收集所有的子文件夹列表,然后顺序设置asset bundle name。命名规格是将路径中的"\"替换为"_"。其中对文件夹的操作用到System.IO下面的接口。
另外添加了黑名单配置列表,用于过滤无需设置asset bundle name的文件夹。(例如导入的插件等)
特别的,为了避免资源冗余,仅对最低层的文件夹设置asset bundle name。
源代码:
using UnityEngine;using System.Collections;using UnityEditor;using System.Collections.Generic;using System.IO;public class AutoGenerateAssetBundleName{    /// <summary>    /// 黑名单    /// </summary>    static public string[] skip_dirs_all = { "testBlackList" };    [MenuItem("Asset Bundle/Auto generate asset bundle name", false, 1)]    public static void GenerateAssetBundleName()    {        string dataPath = Application.dataPath;        string root_path = "";        string sub_dir = "";        int position = dataPath.LastIndexOf(@"/");        if (position != -1)        {            root_path = dataPath.Substring(0, position + 1);            sub_dir = dataPath.Substring(position + 1);        }        ClearAssetBundleName(root_path, sub_dir);        Debug.Log("Begin GenerateAssetBundleName...");        List<string> OutPathList = new List<string>();        List<string> IncludeOutPathList = new List<string>();        OutPathList = GetFilterDirectories(@root_path, @sub_dir);                foreach(string AssetBundleName in OutPathList)        {            AssetImporter importer = AssetImporter.GetAtPath(AssetBundleName);            if (importer != null)            {                importer.assetBundleName = AssetBundleName.Replace('/', '_');                importer.assetBundleVariant = "";            }        }        AssetDatabase.Refresh();        Debug.Log("End GenerateAssetBundleName... Total asset bundle count: " + OutPathList.Count);    }    static List<string> GetFilterDirectories(string root_path, string sub_dir, bool bNeedSkip = true)    {        //需要过滤的文件夹        List<string> skip_dirs = new List<string>(skip_dirs_all);        string sub_folder_name = sub_dir;        int position = sub_dir.LastIndexOf(@"/");        if (position != -1)            sub_folder_name = sub_dir.Substring(position + 1);        if (bNeedSkip)        {            bool bSkipit = false;            foreach(string skip_dir in skip_dirs)            {                if (string.Compare(skip_dir, sub_folder_name, true) == 0)                {                    bSkipit = true;                    break;                }            }            if (bSkipit)            {                return new List<string>();            }        }        string[] dirs = Directory.GetDirectories(root_path + sub_dir, "*", SearchOption.TopDirectoryOnly);        // 提取文件夹名        string[] folder_names = new string[dirs.Length];        for (int i = 0; i < dirs.Length; ++i)        {            int pos = dirs[i].LastIndexOf(@"\");            if (pos != -1)                folder_names[i] = dirs[i].Substring(pos + 1);        }        List<string> filter_dirs = new List<string>();        if (dirs.Length == 0)        {            //没有子目录            //如果sub_folder_name不在skip_dirs内,则设置assetbundlename            bool bFindit = false;            foreach(string skip_dir in skip_dirs)            {                if (string.Compare(skip_dir, sub_folder_name, true) == 0)                {                    bFindit = true;                    break;                }            }            if (!bFindit)            {                Debug.Log("collect valid asset bundle name: " + sub_dir);                filter_dirs.Add(sub_dir);            }            return filter_dirs;        }        foreach (string folder_name in folder_names)        {            List<string> sub_filter_dirs = GetFilterDirectories(root_path, sub_dir + "/" + folder_name);            filter_dirs.AddRange(sub_filter_dirs);        }        return filter_dirs;    }    static void GetAllDirectories(string root_path, string sub_dir, ref List<string> outPathList)    {        string[] dirs = Directory.GetDirectories(root_path + sub_dir, "*", SearchOption.TopDirectoryOnly);        outPathList.Add(sub_dir);        if (dirs.Length > 0)        {            // 提取文件夹名            string[] folder_names = new string[dirs.Length];            for(int i = 0; i < dirs.Length; ++i)            {                int pos = dirs[i].LastIndexOf(@"\");                if (pos != -1)                    folder_names[i] = dirs[i].Substring(pos + 1);            }            foreach(string folder_name in folder_names)            {                GetAllDirectories(root_path, sub_dir + "/" + folder_name, ref outPathList);            }        }    }    static void ClearAssetBundleName(string root_path, string sub_dir)    {        List<string> OutPathList = new List<string>();        GetAllDirectories(@root_path, @sub_dir, ref OutPathList);        foreach(string folder in OutPathList)        {            AssetImporter importer = AssetImporter.GetAtPath(folder);            if (importer != null)            {                importer.assetBundleName = "";            }        }        AssetDatabase.RemoveUnusedAssetBundleNames();        AssetDatabase.Refresh();    }}
运行结果:
运行的log输出

文件夹的asset bundle name:

0 0