IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> Unity一键将Text替换成TextMeshPro -> 正文阅读

[游戏开发]Unity一键将Text替换成TextMeshPro

支持单个替换,以及批量替换。另外,如果面板关联的脚本跟面板名称是一致的,也可以将代码中的Text修改为TextMeshProUGUI

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;
    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();
            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();
        }
    }
    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 Text2TextMeshPro() {
        if (directoryPrefabs != null && directoryPrefabs.Count > 0) {
            if (GUILayout.Button("一键替换")) {
                for (int i = 0 ; i < directoryPrefabs.Count ; i++) {
                    int index = i;
                    Text2TextMeshPro(directoryPrefabs [index]);
                    EditorUtility.DisplayProgressBar("替换进度" , "当前进度" , index / (float)directoryPrefabs.Count);
                }
                EditorUtility.ClearProgressBar();
            }
        }
    }
    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();
    }
}
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-16 22:53:21  更:2022-03-16 22:54:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 -2025/1/16 17:04:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码