2024-02-21
Unity
0
请注意,本文编写于 960 天前,最后修改于 960 天前,其中某些信息可能已经过时。

修改自:https://blog.csdn.net/m0_38066968/article/details/123502044

C#
using System.Collections.Generic; using System.IO; using TMPro; using UnityEditor; using UnityEngine; using UnityEngine.UI; public class Text2TextMeshProUtil : EditorWindow { Vector2 scrollPos = Vector2.zero; static List<string> scriptsFolders; string path; string Path { get { return path; } set { if (value != path) { if (directoryPrefabs == null) { directoryPrefabs = new List<string>(); } else { directoryPrefabs.Clear(); } if (AllAssetPaths == null) { AllAssetPaths = new List<string>(); } else { AllAssetPaths.Clear(); } path = value; } } } static EditorWindow myWindow; static List<string> directoryPrefabs; static List<string> AllAssetPaths; bool showPrefabs = true; private static TMP_FontAsset tmp_Font = null; private static Font font = null; readonly string[] ReplaceMode = { "批量替换", "单个替换" }; int replaceModeIndex; int ReplaceModeIndex { get { return replaceModeIndex; } set { if (value != replaceModeIndex) { if (directoryPrefabs == null) { directoryPrefabs = new List<string>(); } else { directoryPrefabs.Clear(); } if (AllAssetPaths == null) { AllAssetPaths = new List<string>(); } else { AllAssetPaths.Clear(); } Path = ""; replaceModeIndex = value; } } } bool isAutoFixLinkedScripts = true; [MenuItem("Tools/Text2TextMeshPro")] static void Init() { myWindow = EditorWindow.GetWindow(typeof(Text2TextMeshProUtil)); directoryPrefabs = new List<string>(); AllAssetPaths = new List<string>(); scriptsFolders = new List<string> { "Assets/GameMain/Scripts/UI" }; myWindow.minSize = new Vector2(500, 300); } void OnGUI() { isAutoFixLinkedScripts = EditorGUILayout.BeginToggleGroup("修改关联脚本", isAutoFixLinkedScripts); ShowScriptsFolders(); EditorGUILayout.EndToggleGroup(); ReplaceModeIndex = GUILayout.Toolbar(ReplaceModeIndex, ReplaceMode); if (ReplaceModeIndex == 0) { scrollPos = EditorGUILayout.BeginScrollView(scrollPos, new GUILayoutOption[] { GUILayout.Width(myWindow.position.width), GUILayout.Height(myWindow.position.height - scriptsFolders.Count * 20 - 70) }); GetPath(true); ShowAllPrefabs(); EditorGUILayout.EndScrollView(); EditorGUILayout.BeginHorizontal(); LoadPrefab(); Text2TextMeshPro(); TextMeshPro2Text(); EditorGUILayout.EndHorizontal(); } else if (ReplaceModeIndex == 1) { scrollPos = EditorGUILayout.BeginScrollView(scrollPos, new GUILayoutOption[] { GUILayout.Width(myWindow.position.width), GUILayout.Height(myWindow.position.height - scriptsFolders.Count * 20 - 70) }); GetPath(false); ShowAllPrefabs(); EditorGUILayout.EndScrollView(); Text2TextMeshPro(); TextMeshPro2Text(); } } void GetPath(bool isFolder = true) { Event e = Event.current; EditorGUILayout.BeginHorizontal(); GUILayout.Label("Path:", GUILayout.Width(40)); Path = GUILayout.TextField(Path); EditorGUILayout.EndHorizontal(); if (Event.current.type == EventType.DragExited || Event.current.type == EventType.DragUpdated) { if (GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Link; if (Event.current.type == EventType.DragExited) { DragAndDrop.AcceptDrag(); if (!isFolder) { if (DragAndDrop.objectReferences != null && DragAndDrop.objectReferences.Length > 0) { Object[] objectReferences = DragAndDrop.objectReferences; for (int i = 0; i < objectReferences.Length; i++) { int index = i; if (AssetDatabase.GetAssetPath(objectReferences[index]).EndsWith(".prefab")) { if (!directoryPrefabs.Contains(AssetDatabase.GetAssetPath(objectReferences[index]))) { directoryPrefabs.Add(AssetDatabase.GetAssetPath(objectReferences[index])); } } } } } else { if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0) { if (File.Exists(DragAndDrop.paths[0])) { EditorUtility.DisplayDialog("警告", "批量模式下请拖拽文件夹!", "确定"); return; } Path = DragAndDrop.paths[0]; } } } e.Use(); } else { DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; } } } void ShowAllPrefabs() { if (directoryPrefabs != null && directoryPrefabs.Count > 0) { showPrefabs = EditorGUILayout.Foldout(showPrefabs, "显示预制体"); if (showPrefabs) { for (int i = 0; i < directoryPrefabs.Count; i++) { int index = i; EditorGUILayout.BeginHorizontal(); EditorGUILayout.SelectableLabel($"预制体路径:{directoryPrefabs[index]}"); if (GUILayout.Button("查看", GUILayout.Width(60))) { EditorGUIUtility.PingObject(AssetDatabase.LoadAssetAtPath<Object>(directoryPrefabs[index])); Selection.activeGameObject = AssetDatabase.LoadAssetAtPath<Object>(directoryPrefabs[index]) as GameObject; } if (GUILayout.Button("删除", GUILayout.Width(60))) { directoryPrefabs.RemoveAt(index); } EditorGUILayout.EndHorizontal(); } } else { if (GUILayout.Button("清空选择", GUILayout.Width(60))) { directoryPrefabs.Clear(); AllAssetPaths.Clear(); Path = ""; } } } } void LoadPrefab() { if (GUILayout.Button("加载预制体")) { if (!string.IsNullOrEmpty(Path)) { DirectoryInfo direction = new DirectoryInfo(Path); FileInfo[] files = direction.GetFiles("*.prefab", SearchOption.AllDirectories); for (int i = 0; i < files.Length; i++) { int startindex = files[i].FullName.IndexOf("Assets"); string unityPath = files[i].FullName.Substring(startindex); if (!directoryPrefabs.Contains(unityPath)) { directoryPrefabs.Add(unityPath); } } } } } void TextMeshPro2Text() { if (directoryPrefabs != null && directoryPrefabs.Count > 0) { if (GUILayout.Button("一键替换 TextMeshPro2Text")) { for (int i = 0; i < directoryPrefabs.Count; i++) { int index = i; TextMeshpro2Text(directoryPrefabs[index]); EditorUtility.DisplayProgressBar("替换进度", "当前进度", index / (float)directoryPrefabs.Count); } EditorUtility.ClearProgressBar(); } } } void Text2TextMeshPro() { if (directoryPrefabs != null && directoryPrefabs.Count > 0) { if (GUILayout.Button("一键替换 Text2TextMeshPro")) { for (int i = 0; i < directoryPrefabs.Count; i++) { int index = i; Text2TextMeshPro(directoryPrefabs[index]); EditorUtility.DisplayProgressBar("替换进度", "当前进度", index / (float)directoryPrefabs.Count); } EditorUtility.ClearProgressBar(); } } } void TextMeshpro2Text(string path) { GameObject root = PrefabUtility.LoadPrefabContents(path); if (root) { TextMeshProUGUI[] list = root.GetComponentsInChildren<TextMeshProUGUI>(true); for (int i = 0; i < list.Length; i++) { TextMeshProUGUI text = list[i]; Transform target = text.transform; Vector2 size = text.rectTransform.sizeDelta; string strContent = text.text; Color color = text.color; int fontSize = (int)text.fontSize; TMPro.FontStyles fontStyle = text.fontStyle; TMPro.TextAlignmentOptions textAnchor = text.alignment; bool supportRichText = text.richText; bool enableWordWrapping = text.enableWordWrapping; TextOverflowModes verticalWrapMode = text.overflowMode; bool raycastTarget = text.raycastTarget; GameObject.DestroyImmediate(text); Text text2 = target.gameObject.AddComponent<Text>(); if (text2 == null) { Debug.LogError("添加失败: " + path); continue; } text2.rectTransform.sizeDelta = size; text2.text = strContent; text2.color = color; text2.fontSize = fontSize; text2.fontStyle = fontStyle == FontStyles.Bold ? FontStyle.BoldAndItalic : (FontStyle)fontStyle; //Outline outLine = target.gameObject.AddComponent<Outline>(); //outLine.effectColor = new Color(0, 0, 0, 1f); //outLine.effectDistance = new Vector2(3, 3); switch (textAnchor) { case TextAlignmentOptions.TopLeft: text2.alignment = TextAnchor.UpperLeft; break; case TextAlignmentOptions.Top: text2.alignment = TextAnchor.UpperCenter; break; case TextAlignmentOptions.TopRight: text2.alignment = TextAnchor.UpperRight; break; case TextAlignmentOptions.MidlineLeft: text2.alignment = TextAnchor.MiddleLeft; break; case TextAlignmentOptions.Midline: text2.alignment = TextAnchor.MiddleCenter; break; case TextAlignmentOptions.MidlineRight: text2.alignment = TextAnchor.MiddleRight; break; case TextAlignmentOptions.BottomLeft: text2.alignment = TextAnchor.LowerLeft; break; case TextAlignmentOptions.Bottom: text2.alignment = TextAnchor.LowerCenter; break; case TextAlignmentOptions.BottomRight: text2.alignment = TextAnchor.LowerRight; break; } text2.supportRichText = supportRichText; if (text.overflowMode == TextOverflowModes.Overflow) { text2.verticalOverflow = VerticalWrapMode.Overflow; } else { text2.horizontalOverflow = text.enableWordWrapping ? HorizontalWrapMode.Wrap : HorizontalWrapMode.Overflow; } text2.raycastTarget = raycastTarget; } } PrefabUtility.SaveAsPrefabAsset(root, path, out bool success); if (!success) { Debug.LogError($"预制体:{path} 保存失败!"); } if (isAutoFixLinkedScripts) { ChangeScriptsTextMeshPro2Text(); } } void Text2TextMeshPro(string path) { GameObject root = PrefabUtility.LoadPrefabContents(path); if (root) { Text[] list = root.GetComponentsInChildren<Text>(true); for (int i = 0; i < list.Length; i++) { Text text = list[i]; Transform target = text.transform; Vector2 size = text.rectTransform.sizeDelta; string strContent = text.text; Color color = text.color; int fontSize = text.fontSize; FontStyle fontStyle = text.fontStyle; TextAnchor textAnchor = text.alignment; bool richText = text.supportRichText; HorizontalWrapMode horizontalWrapMode = text.horizontalOverflow; VerticalWrapMode verticalWrapMode = text.verticalOverflow; bool raycastTarget = text.raycastTarget; GameObject.DestroyImmediate(text); TextMeshProUGUI textMeshPro = target.gameObject.AddComponent<TextMeshProUGUI>(); if (tmp_Font == null) { tmp_Font = Resources.Load<TMP_FontAsset>("MyTextMesh"); } textMeshPro.rectTransform.sizeDelta = size; textMeshPro.text = strContent; textMeshPro.color = color; textMeshPro.fontSize = fontSize; textMeshPro.fontStyle = fontStyle == FontStyle.BoldAndItalic ? FontStyles.Bold : (FontStyles)fontStyle; switch (textAnchor) { case TextAnchor.UpperLeft: textMeshPro.alignment = TextAlignmentOptions.TopLeft; break; case TextAnchor.UpperCenter: textMeshPro.alignment = TextAlignmentOptions.Top; break; case TextAnchor.UpperRight: textMeshPro.alignment = TextAlignmentOptions.TopRight; break; case TextAnchor.MiddleLeft: textMeshPro.alignment = TextAlignmentOptions.MidlineLeft; break; case TextAnchor.MiddleCenter: textMeshPro.alignment = TextAlignmentOptions.Midline; break; case TextAnchor.MiddleRight: textMeshPro.alignment = TextAlignmentOptions.MidlineRight; break; case TextAnchor.LowerLeft: textMeshPro.alignment = TextAlignmentOptions.BottomLeft; break; case TextAnchor.LowerCenter: textMeshPro.alignment = TextAlignmentOptions.Bottom; break; case TextAnchor.LowerRight: textMeshPro.alignment = TextAlignmentOptions.BottomRight; break; } textMeshPro.richText = richText; if (verticalWrapMode == VerticalWrapMode.Overflow) { textMeshPro.enableWordWrapping = true; textMeshPro.overflowMode = TextOverflowModes.Overflow; } else { textMeshPro.enableWordWrapping = horizontalWrapMode == HorizontalWrapMode.Overflow ? false : true; } textMeshPro.raycastTarget = raycastTarget; } } PrefabUtility.SaveAsPrefabAsset(root, path, out bool success); if (!success) { Debug.LogError($"预制体:{path} 保存失败!"); } if (isAutoFixLinkedScripts) { ChangeScriptsText2TextMeshPro(); } } void ShowScriptsFolders() { for (int i = 0; i < scriptsFolders.Count; i++) { int index = i; EditorGUILayout.BeginHorizontal(); SelectScriptsFolder(index); EditorGUILayout.EndHorizontal(); } } void SelectScriptsFolder(int index) { Event e = Event.current; EditorGUILayout.BeginHorizontal(); GUILayout.Label($"scriptsFolder{index + 1}:", GUILayout.Width(80)); scriptsFolders[index] = GUILayout.TextField(scriptsFolders[index], GUILayout.Width(200)); if (Event.current.type == EventType.DragExited || Event.current.type == EventType.DragUpdated) { if (GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition)) { DragAndDrop.visualMode = DragAndDropVisualMode.Link; if (Event.current.type == EventType.DragExited) { DragAndDrop.AcceptDrag(); if (DragAndDrop.paths != null && DragAndDrop.paths.Length > 0) { if (File.Exists(DragAndDrop.paths[0])) { EditorUtility.DisplayDialog("警告", "请选择文件夹!", "确定"); return; } scriptsFolders[index] = DragAndDrop.paths[0]; } } e.Use(); } else { DragAndDrop.visualMode = DragAndDropVisualMode.Rejected; } } if (GUILayout.Button("添加路径")) { scriptsFolders.Add(scriptsFolders[scriptsFolders.Count - 1]); } if (GUILayout.Button("删除路径")) { if (scriptsFolders.Count == 1) { EditorUtility.DisplayDialog("警告", "仅剩最后一个文件夹,删除将会出错!", "确定"); return; } scriptsFolders.RemoveAt(index); } EditorGUILayout.EndHorizontal(); } void ChangeScriptsText2TextMeshPro() { AllAssetPaths.Clear(); Debug.LogError(directoryPrefabs.Count); if (directoryPrefabs != null && directoryPrefabs.Count > 0) { for (int i = 0; i < directoryPrefabs.Count; i++) { int index = i; string scriptsName = System.IO.Path.GetFileNameWithoutExtension(directoryPrefabs[index]); string[] tmp = AssetDatabase.FindAssets($"{scriptsName} t:Script", scriptsFolders.ToArray()); if (tmp != null && tmp.Length > 0) { AllAssetPaths.AddRange(tmp); } } for (int i = 0; i < AllAssetPaths.Count; i++) { int index = i; ChangeScriptsText2TextMeshPro(AssetDatabase.GUIDToAssetPath(AllAssetPaths[index])); } } AssetDatabase.Refresh(); } void ChangeScriptsText2TextMeshPro(string script) { StreamReader sr = new StreamReader(script); string str = sr.ReadToEnd(); sr.Close(); str = str.Replace("<Text>", "<TMPro.TextMeshProUGUI>"); str = str.Replace(" Text ", " TMPro.TextMeshProUGUI "); StreamWriter sw = new StreamWriter(script, false, System.Text.Encoding.UTF8); sw.Write(str); sw.Close(); } void ChangeScriptsTextMeshPro2Text() { AllAssetPaths.Clear(); Debug.LogError(directoryPrefabs.Count); if (directoryPrefabs != null && directoryPrefabs.Count > 0) { for (int i = 0; i < directoryPrefabs.Count; i++) { int index = i; string scriptsName = System.IO.Path.GetFileNameWithoutExtension(directoryPrefabs[index]); string[] tmp = AssetDatabase.FindAssets($"{scriptsName} t:Script", scriptsFolders.ToArray()); if (tmp != null && tmp.Length > 0) { AllAssetPaths.AddRange(tmp); } } for (int i = 0; i < AllAssetPaths.Count; i++) { int index = i; ChangeScriptsTextMeshPro2Text(AssetDatabase.GUIDToAssetPath(AllAssetPaths[index])); } } AssetDatabase.Refresh(); } void ChangeScriptsTextMeshPro2Text(string script) { StreamReader sr = new StreamReader(script); string str = sr.ReadToEnd(); sr.Close(); str = str.Replace("<TMPro.TextMeshProUGUI>", "<Text>"); str = str.Replace(" TMPro.TextMeshProUGUI ", " Text "); str = str.Replace(" TextMeshProUGUI ", " Text "); StreamWriter sw = new StreamWriter(script, false, System.Text.Encoding.UTF8); sw.Write(str); sw.Close(); } }

本文作者:Void

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!