Unity编辑器

Unity编辑器 - 资源批处理工具基类

经常要对资源进行批处理,很多时候都是一次性的需求,于是弄个通用脚本。
工具是个弹出面板,处理过程有进度条,如下:

批处理工具例子

如图,子类只需要重写几个方法:

using UnityEngine;
using BatchTool;
using UnityEditor;

public class TestBatchTool : BatchToolBase {

    [MenuItem("BatchTool/test")]
    static void test() {
        GetWindow<TestBatchTool>();
    }

    ModelImporterAnimationType animType;
    bool bImportMat;

    /// <summary>
    /// 初始化信息
    /// </summary>
    /// <param name="pTitle">进度条标题</param>
    /// <param name="pInfo">进度条显示信息开头</param>
    /// <param name="fileExt">需要处理文件的后缀名</param>
    protected override void InitTool(out string pTitle, out string pInfo, out string fileExt) {
        base.InitTool(out pTitle, out pInfo, out fileExt);
        fileExt = ".fbx";
    }

    /// <summary>
    /// 处理一个资源的逻辑
    /// </summary>
    /// <param name="path">资源相对路径</param>
    protected override void ExcuteOnePath(string path) {
        Debug.Log(path);
    }

    /// <summary>
    /// 批处理选项
    /// </summary>
    protected override void GUIBatchOptions() {
        base.GUIBatchOptions();
        animType = (ModelImporterAnimationType)EditorGUILayout.EnumPopup("Animation Type", animType);
        bImportMat = EditorGUILayout.Toggle("Import Material", bImportMat);
    }
}

基类代码:

using System;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace BatchTool {
    public class BatchToolBase : EditorWindow {
        private string _folderPath;
        protected string FolderPath {
            get {
                if (string.IsNullOrEmpty(_folderPath))
                    _folderPath = "Assets";
                return _folderPath;
            }

            set {
                string pstr = Directory.GetParent(Application.dataPath).FullName;
                pstr = pstr.Replace("\", "/");
                if (value != null && value.Contains(pstr))
                    _folderPath = value.Replace(pstr + "/", "");
                else
                    _folderPath = value;
            }
        }

        private string _processTitle = string.Empty;
        private string _processInfo = string.Empty;
        private string _fileNameExt = ".prefab";

        private string[] _allAssetPaths;

        private Rect _drawRect = Rect.zero;

        protected void OnEnable() {
            minSize = new Vector2(100,150);
            position = new Rect(300, 300, 260, 180);
            Repaint();
            _allAssetPaths = AssetDatabase.GetAllAssetPaths();
            InitTool(out _processTitle,out _processInfo,out _fileNameExt);
            EditorUtility.ClearProgressBar();
        }

        protected virtual void InitTool
            (out string pTitle, out string pInfo, out string fileExt) {
            pTitle = "批处理";
            pInfo = "正在处理: ";
            fileExt = ".prefab";
        }

        protected void OnGUI() {
            _drawRect.position = Vector2.zero;
            _drawRect.size = position.size;
            _drawRect.x += 5;
            _drawRect.width -= 10f;
            _drawRect.y += 5;
            _drawRect.height -= 10f;
            GUILayout.BeginArea(_drawRect);
            {
                GUISelectFolderPath();
                GUILayout.Space(5);
                GUIBatchOptions();
                GUILayout.Space(5);
                GUIBeginBatchBtn();
            }
            GUILayout.EndArea();
        }

        private void GUIBeginBatchBtn() {
            Rect rect = GUILayoutUtility.GetRect(GUIContent.none, EditorStyles.largeLabel, GUILayout.Height(25));
            rect.x += 5f;
            rect.width -= 10f;
            if (GUI.Button(rect, "开始批处理!")) {
                if (!Directory.Exists(FolderPath)) {
                    Debug.LogError("文件夹不存在!");
                    return;
                }

                var filterCollection = from path in _allAssetPaths
                                       where FilterPathFun(path)
                                       select path;

                var paths = filterCollection.ToList();

                float iterateCount = 0;
                float proccesCount = 0;
                foreach (var path in paths) {
                    iterateCount++;
                    var procValue = iterateCount / paths.Count;
                    if (EditorUtility.DisplayCancelableProgressBar(_processTitle, _processInfo + path, procValue)) {
                        Debug.Log("取消批处理!");
                        EditorUtility.ClearProgressBar();
                        break;
                    }
                    ExcuteOnePath(path);
                    proccesCount++;
                }

                EditorUtility.ClearProgressBar();
                OnComplete(paths.Count, proccesCount);
            }
        }

        protected virtual void OnComplete(int count, float proccesCount) {
            Debug.Log("遍历了 " + count + "个文件,实际处理了 " + proccesCount + " 个文件!");
        }

        protected virtual void ExcuteOnePath(string path) {
            Debug.Log("NotImplementedException!!!!");
        }

        protected virtual bool FilterPathFun(string path) {
            bool isExtention = Path.GetExtension(path).ToLower() == _fileNameExt;
            bool isInFolder = path.Substring(0, FolderPath.Length) == FolderPath;
            return isExtention && isInFolder;
        }

        protected virtual void GUIBatchOptions() {
            GUILayout.Label("批处理设置:");
        }

        private void GUISelectFolderPath() {
            GUILayout.BeginHorizontal();
            {
                EditorGUIUtility.labelWidth = 45f;

                GUI.SetNextControlName("inputPath");
                FolderPath = EditorGUILayout.TextField("文件夹:", FolderPath);
                var rect = GUILayoutUtility.GetLastRect();
                if (rect.width > 2 && GUI.GetNameOfFocusedControl() == "inputPath") {
                    if (Event.current.clickCount > 0 && !rect.Contains(Event.current.mousePosition)) {
                        GUI.FocusControl(null);
                        Repaint();
                    }
                }

                if (GUILayout.Button("", GUILayout.Width(25), GUILayout.Height(14))) {
                    FolderPath = EditorUtility.OpenFolderPanel("Select a folder", "Assets", "");
                }
                EditorGUIUtility.labelWidth = 0;
            }
            GUILayout.EndHorizontal();
        }
    }
}
原文地址:https://www.cnblogs.com/CloudLiu/p/10746066.html