#if UNITY_EDITOR using UnityEngine; using UnityEditor; using UnityEngine.UI; using System.Collections.Generic; using System.IO; namespace Kill.Editor { /// /// 批量字体替换工具 /// 一次性替换项目中所有 Text 组件的字体 /// public class BatchFontReplacer : EditorWindow { private Font targetFont; private bool includeInactive = true; private bool includePrefabs = true; private Vector2 scrollPosition; private List modifiedObjects = new List(); [MenuItem("Tools/批量替换字体")] static void OpenWindow() { GetWindow("批量替换字体"); } void OnGUI() { GUILayout.Label("批量替换字体工具", EditorStyles.boldLabel); EditorGUILayout.Space(); // 选择目标字体 targetFont = (Font)EditorGUILayout.ObjectField( "目标字体", targetFont, typeof(Font), false); if (targetFont == null) { EditorGUILayout.HelpBox("请选择一个中文字体文件", MessageType.Warning); return; } EditorGUILayout.Space(); // 选项 includeInactive = EditorGUILayout.Toggle("包含未激活的物体", includeInactive); includePrefabs = EditorGUILayout.Toggle("包含预制体资源", includePrefabs); EditorGUILayout.Space(); // 按钮 EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("替换场景中的 Text", GUILayout.Height(30))) { ReplaceFontsInScene(); } if (GUILayout.Button("替换预制体中的 Text", GUILayout.Height(30))) { ReplaceFontsInPrefabs(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.Space(); if (GUILayout.Button("一键替换全部", GUILayout.Height(40))) { ReplaceAllFonts(); } EditorGUILayout.Space(); // 显示修改记录 if (modifiedObjects.Count > 0) { GUILayout.Label($"已修改 {modifiedObjects.Count} 个对象:", EditorStyles.boldLabel); scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition, GUILayout.Height(200)); foreach (var obj in modifiedObjects) { EditorGUILayout.LabelField(obj); } EditorGUILayout.EndScrollView(); } } /// /// 替换场景中的所有 Text /// private void ReplaceFontsInScene() { if (targetFont == null) return; modifiedObjects.Clear(); int count = 0; // 获取场景中的所有 Text Text[] texts = Resources.FindObjectsOfTypeAll(); foreach (var text in texts) { // 只处理场景中的物体 if (!text.gameObject.scene.IsValid()) continue; // 检查是否未激活 if (!includeInactive && !text.gameObject.activeInHierarchy) continue; // 替换字体 if (text.font != targetFont) { Undo.RecordObject(text, "Replace Font"); text.font = targetFont; EditorUtility.SetDirty(text); modifiedObjects.Add($"[场景] {text.gameObject.name}"); count++; } } Debug.Log($"[批量替换字体] 场景中共替换了 {count} 个 Text 组件"); } /// /// 替换所有预制体中的 Text /// private void ReplaceFontsInPrefabs() { if (targetFont == null) return; modifiedObjects.Clear(); int count = 0; // 查找所有预制体文件 string[] prefabGuids = AssetDatabase.FindAssets("t:Prefab", new[] { "Assets" }); foreach (string guid in prefabGuids) { string path = AssetDatabase.GUIDToAssetPath(guid); GameObject prefab = AssetDatabase.LoadAssetAtPath(path); if (prefab == null) continue; // 获取预制体中的所有 Text Text[] texts = prefab.GetComponentsInChildren(true); bool modified = false; foreach (var text in texts) { if (text.font != targetFont) { text.font = targetFont; modified = true; count++; } } // 保存修改 if (modified) { EditorUtility.SetDirty(prefab); modifiedObjects.Add($"[预制体] {path}"); } } // 保存所有修改 AssetDatabase.SaveAssets(); Debug.Log($"[批量替换字体] 预制体中共替换了 {count} 个 Text 组件"); } /// /// 一键替换全部 /// private void ReplaceAllFonts() { if (targetFont == null) { EditorUtility.DisplayDialog("错误", "请先选择一个字体", "确定"); return; } if (EditorUtility.DisplayDialog("确认", "这将替换项目中所有 Text 组件的字体,是否继续?", "确定", "取消")) { ReplaceFontsInScene(); ReplaceFontsInPrefabs(); EditorUtility.DisplayDialog("完成", $"共替换了 {modifiedObjects.Count} 个对象", "确定"); } } } } #endif