工具如图所示:
GUI绘制逻辑:
using UnityEditor;
using UnityEngine;
using System.Linq;
using UnityEngine.UI;
using System.Collections.Generic;
public class FontEditor : EditorWindow
{
private Font m_Src;
private Font m_Target;
private string m_Dir = string.Empty;
private Vector2 m_Scroll = Vector2.zero;
private Dictionary<string, bool> m_PathSelect = new Dictionary<string, bool>();
private Dictionary<UnityEngine.GameObject, bool> m_PrefabExpand = new Dictionary<UnityEngine.GameObject, bool>();
private Dictionary<UnityEngine.GameObject, List<string>> m_PrefabPaths = new Dictionary<UnityEngine.GameObject, List<string>>();
[MenuItem("Window/自定义/字体替换工具")]
private static void ShowXX()
{
var window = EditorWindow.GetWindow<FontEditor>();
window.titleContent = new GUIContent("字体替换工具");
window.Show();
}
private void OnInspectorUpdate()
{
this.Repaint();
}
private void OnGUI()
{
GUILayout.BeginHorizontal();
m_Dir = EditorGUILayout.TextField(new GUIContent("查找目录:"), m_Dir);
if (GUILayout.Button("浏览"))
{
m_Dir = EditorUtility.OpenFolderPanel("选择目录", string.IsNullOrEmpty(m_Dir) ? "Assets" : m_Dir, "Assets");
if (!string.IsNullOrEmpty(m_Dir))
m_Dir = m_Dir.Replace(Application.dataPath, "Assets");
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
m_Src = EditorGUILayout.ObjectField(new GUIContent("原始字体:"), m_Src, typeof(Font), false) as Font;
if (GUILayout.Button("查找"))
{
if (m_Src == null) return;
Search();
}
m_Target = EditorGUILayout.ObjectField(new GUIContent("原始字体:"), m_Target, typeof(Font), false) as Font;
if (GUILayout.Button("替换"))
{
if (m_Src == null || m_Target == null) return;
Replace();
}
GUILayout.EndHorizontal();
m_Scroll = EditorGUILayout.BeginScrollView(m_Scroll);
var keys = m_PrefabExpand.Keys.ToList();
foreach (var key in keys)
{
var assetPath = AssetDatabase.GetAssetPath(key);
if (!m_PrefabPaths.ContainsKey(key)) continue;
m_PrefabExpand[key] = EditorGUILayout.BeginFoldoutHeaderGroup(m_PrefabExpand[key], assetPath);
if (m_PrefabExpand[key])
{
var paths = m_PrefabPaths[key];
foreach (var path in paths)
{
if (!m_PathSelect.ContainsKey(path))
m_PathSelect[path] = true;
GUILayout.BeginHorizontal();
m_PathSelect[path] = EditorGUILayout.ToggleLeft(path, m_PathSelect[path]);
if(GUILayout.Button("定位"))
{
Selection.activeObject = key;
}
GUILayout.EndHorizontal();
}
}
EditorGUILayout.EndFoldoutHeaderGroup();
}
if (m_PrefabExpand.Count == 0)
{
GUILayout.Label("无内容");
}
EditorGUILayout.EndScrollView();
}
private void Search()
{
m_PrefabExpand.Clear();
m_PrefabPaths.Clear();
m_PathSelect.Clear();
EditorTools.Foreach<GameObject>("", "t:prefab", string.IsNullOrEmpty(m_Dir) ? "Assets" : m_Dir, obj =>
{
var txt = obj.GetComponentsInChildren<Text>(true);
foreach (var t in txt)
{
if (t.font != m_Src) continue;
if (!m_PrefabExpand.ContainsKey(obj))
m_PrefabExpand[obj] = false;
List<string> list = null;
if (m_PrefabPaths.ContainsKey(obj))
{
list = m_PrefabPaths[obj];
}
else
{
list = new List<string>();
}
var full = EditorTools.GetFullPath(t.transform);
if (!list.Contains(full))
list.Add(full);
m_PrefabPaths[obj] = list;
m_PathSelect[full] = true;
}
});
}
private void Replace()
{
var objs = m_PrefabExpand.Keys.ToList();
foreach (var obj in objs)
{
var assetPath = AssetDatabase.GetAssetPath(obj);
if (!m_PrefabPaths.ContainsKey(obj))
{
UnityEngine.Debug.LogError(assetPath + "不存在路径");
continue;
}
var paths = m_PrefabPaths[obj];
var changed = false;
foreach (var path in paths)
{
if (!m_PathSelect.ContainsKey(path))
{
UnityEngine.Debug.LogError(path + "不存在路径m_PathSelect");
continue;
}
if (!m_PathSelect[path])
{
UnityEngine.Debug.LogError(path + "不存在路径111m_PathSelect");
continue;
}
var relPath = path.Replace(obj.name + "/", "");
var child = obj.transform.Find(relPath);
if (child == null)
{
UnityEngine.Debug.LogError(relPath + "111不存在路径111m_PathSelect");
continue;
}
var txt = child.GetComponent<Text>();
if (txt == null)
{
UnityEngine.Debug.LogError(relPath + "txt不存在路径111m_PathSelect");
continue;
}
if (txt.font != m_Target)
{
txt.font = m_Target;
changed = true;
}
}
if (changed)
{
PrefabUtility.SavePrefabAsset(obj, out bool suc);
if (!suc)
{
UnityEngine.Debug.LogError(assetPath + "保存失败");
}
else
{
UnityEngine.Debug.Log(assetPath + "保存成功");
}
}
else
{
UnityEngine.Debug.Log(assetPath + "未发生变化");
}
}
}
}