using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor; using System; using UnityEngine.UI; using TMPro; using System.Reflection; namespace TFramework { public class BatchTool : EditorWindow { static BatchTool win; static Transform _root; string[] _operate = new string[] { "更改UI显示优先级","替换材质" ,"规范命名","组件批处理"}; int _currentOpIndex=0; private Rect _splitRect = Rect.zero; private float _splitterWidth = 5; private bool _isDrag = false; private float _minWidth = 60; private float _maxWidth = 250; private float _opMenuWidth = 100; Material _overlay; Material _meshPro; [MenuItem("TFramework/批处理")] private static void OpenWin() { win = GetWindow(); win.titleContent.text = "批处理工具"; win.minSize = new Vector2(300, 500); win.maxSize = new Vector2(500, 500); win.Show(); } private void OnEnable() { _overlay = AssetDatabase.LoadAssetAtPath("Assets/TFramework/Runtime/Materails/UI/Overlay.mat"); _meshPro = AssetDatabase.LoadAssetAtPath("Assets/TFramework/Runtime/Materails/UI/OverlayMeshProUGUI.mat"); InitComponentBatch(); } private void OnGUI() { using(new EditorGUILayout.HorizontalScope()) { EditorGUILayout.LabelField("根节点"); _root = EditorGUILayout.ObjectField(_root, typeof(Transform), true) as Transform; } GUILayout.BeginHorizontal(); DrawOpMenu(); SplitterGUI(); ExecuteOp(); GUILayout.EndHorizontal(); EventHandle(); } void DrawOpMenu() { GUILayout.BeginVertical("PreBackground", GUILayout.Width(_opMenuWidth)); for (int i = 0; i < _operate.Length; i++) { string style = _currentOpIndex == i ? "TV Selection" : "PrefixLabel"; int index = i; if (GUILayout.Button(_operate[i],style)) { _currentOpIndex = index; } } GUILayout.EndVertical(); } private void ExecuteOp() { switch (_operate[_currentOpIndex]) { case "更改UI显示优先级": ChangeUIShowPriority(); break; case "替换材质": GUILayout.Label("功能暂未实现"); MatReplace(); break; case "规范命名": GUILayout.Label("功能暂未实现"); break; case "组件批处理": ComponentBatch(); break; default: break; } } private void ChangeUIShowPriority() { GUILayout.BeginVertical(); if(_root) { using(new EditorGUILayout.HorizontalScope()) { GUILayout.Label("LegacyUI预备材质"); _overlay = (Material)EditorGUILayout.ObjectField(_overlay, typeof(Material), true); } using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("MeshProUI预备材质"); _meshPro = (Material)EditorGUILayout.ObjectField(_meshPro, typeof(Material), true); } if (GUILayout.Button("开始更改")) { Graphic[] graphics = _root.GetComponentsInChildren(true); for (int i = 0; i < graphics.Length; i++) { if (graphics[i] is TextMeshProUGUI) graphics[i].materialForRendering.shader = _meshPro.shader; else { if (!graphics[i].material.name.Equals("Default UI Material")) continue; graphics[i].material = _overlay; } } EditorUtility.SetDirty(_root); AssetDatabase.SaveAssets(); Log.Info("更改完成!"); } } else { EditorGUILayout.LabelField("请指定一个根节点!"); } GUILayout.EndVertical(); } public static void MatReplace() { } private static MethodInfo _selectionAddMethod; private static Type _componentType; private static string _componentTypeFilter = ""; private static bool _includeInactive = true; private static object[] _parameter = new object[1]; public static void InitComponentBatch() { if(_selectionAddMethod==null) { MethodInfo[] methods = GlobalTool.GetTypeToCurrentDomain("UnityEditor.Selection").GetMethods(BindingFlags.Static | BindingFlags.NonPublic); for (int i = 0; i < methods.Length; i++) { if(methods[i].Name=="Add") { ParameterInfo[] parameter = methods[i].GetParameters(); if(parameter!=null&¶meter.Length==1&¶meter[0].ParameterType.Name=="Object") { _selectionAddMethod = methods[i]; break; } } } } } public static void ComponentBatch() { EditorGUILayout.BeginVertical(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.HelpBox("批处理[ " + (_root ? _root.name : "Root") + " ]下的[ " + (_componentType != null ? _componentType.FullName : "Component") + " ]组件!", MessageType.Info); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("筛选词条:", GUILayout.Width(120)); _componentTypeFilter = EditorGUILayout.TextField(_componentTypeFilter); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("组件:", GUILayout.Width(120)); if (GUILayout.Button(_componentType != null ? _componentType.FullName : "", "MiniPopup")) { GenericMenu gm = new GenericMenu(); List types = GlobalTool.GetTypesInRunTimeAssemblies(type => { return type.IsSubclassOf(typeof(Component)) && type.FullName.ToLower().Contains(_componentTypeFilter.ToLower()); }); gm.AddItem(new GUIContent(""), _componentType == null, () => { _componentType = null; }); for (int i = 0; i < types.Count; i++) { Type type = types[i]; gm.AddItem(new GUIContent(type.FullName.Replace(".", "/")), type == _componentType, () => { _componentType = type; }); } gm.ShowAsContext(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); GUILayout.Label("包含未激活对象:", GUILayout.Width(120)); _includeInactive = EditorGUILayout.Toggle(_includeInactive); EditorGUILayout.EndHorizontal(); GUI.enabled = _root && _componentType != null && _selectionAddMethod != null; EditorGUILayout.BeginHorizontal(); GUI.backgroundColor = Color.green; if (GUILayout.Button("Collect")) { Selection.activeGameObject = null; Component[] components = _root.transform.GetComponentsInChildren(_componentType, _includeInactive); for (int i = 0; i < components.Length; i++) { _parameter[0] = components[i]; _selectionAddMethod.Invoke(null, _parameter); } } GUI.backgroundColor = Color.white; EditorGUILayout.EndHorizontal(); GUI.enabled = true; EditorGUILayout.EndVertical(); } private void SplitterGUI() { GUILayout.Box("", "PreVerticalScrollbarThumb", GUILayout.Width(_splitterWidth), GUILayout.MaxWidth(_splitterWidth), GUILayout.MinWidth(_splitterWidth), GUILayout.ExpandHeight(true)); _splitRect = GUILayoutUtility.GetLastRect(); EditorGUIUtility.AddCursorRect(_splitRect, MouseCursor.SplitResizeLeftRight); } private void EventHandle() { if (Event.current != null) { switch (Event.current.rawType) { case EventType.MouseDown: GUI.FocusControl(null); if (_splitRect.Contains(Event.current.mousePosition)) _isDrag = true; break; case EventType.MouseDrag: if (_isDrag) { _opMenuWidth += Event.current.delta.x; if (_opMenuWidth <= _minWidth) _opMenuWidth = _minWidth; else if (_opMenuWidth >= _maxWidth) _opMenuWidth = _maxWidth; GUI.changed = true; } break; case EventType.MouseUp: _isDrag = false; break; } } } } }