Unity编辑器下,界面替换NGUI字体以及字号

时间:2023-03-09 02:56:33
Unity编辑器下,界面替换NGUI字体以及字号

项目中有需要批量替换字体以及字号的需求,一般也就是多语言处理吧。

提供界面如下:

Unity编辑器下,界面替换NGUI字体以及字号

手机拍图,就这样凑合看吧。但是代码不打折。

紧急避让,我只提供修改UILabel以及UIPopupList 下的字体,字号。其他需求的,可以绕远了。还有哈,代码写的很渣渣,因为自己用嘛。还有所有权归我本人所有,一切用于商业用途的,请自己联系博主,上缴费用,谢谢~~~~(赚钱好方法)

using UnityEngine;
using System.Collections;
using UnityEditor;
using System.IO; //
public class ReplaceFontEditor
{
[MenuItem("XmlTest/打开替换字体窗口", false, )]
static void OpenReplaceFontEditor()
{
UIReplaceFontEditorWindow.Init();
}
}
 using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System;
using System.IO;
using System.Text;
using LuaInterface; public class FontInfo
{ } public class UIReplaceFontEditorWindow : EditorWindow
{
private static UIReplaceFontEditorWindow window; private static Dictionary<string, Font> allFonts = new Dictionary<string, Font>(); // key: fontName, value : Font
private static Dictionary<string, HashSet<int>> allFontsSize = new Dictionary<string, HashSet<int>>(); // key: fontName, value :Hash<int>, Hash<int> 保存所有的字号(去重)
private static Dictionary<string, Dictionary<int, HashSet<string>>> allFontNameSizePrefabName = new Dictionary<string, Dictionary<int, HashSet<string>>>(); // key : fontName, value: < key:fontSize, value: prefabNames > private static List<GameObject> allNeedReplacePrefab = new List<GameObject>();
private static string[] allFontName = new string[]; // 预先分配
private static string writefileinfo = "字体名称、字号文件(fontsizeinfo.txt)写入状态:空闲状态 ";
// prefab文字信息保存目录
private static string prefabFontSizeInfoSaveDir = "dir name";
private int ID = -;
// 待替换字体
public Font previousFont = null;
private string previourFontSelectInfo = "";
// 新字体
public Font newFont = null;
private string newFontSelectInfo = "";
// 字体对应文件
public string fontSizeFilePath = "file name";
private string fontSizeFilePathSelectInfo = "";
// 保存字号对应文件
private ArrayList fontSizeArray = new ArrayList();
// 新prefab保存目录
public string newPrefabSaveDir = "dir name"; private string objpath_test = ""; public static void Init()
{
// Get existing open window or if none, make a new one:
window = (UIReplaceFontEditorWindow)EditorWindow.GetWindow<UIReplaceFontEditorWindow>("替换字体窗口",true); StaticInitData();
} static void StaticInitData()
{
allFonts.Clear();
foreach (var item in allFontsSize)
{
item.Value.Clear();
}
allFontsSize.Clear();
allNeedReplacePrefab.Clear();
for (int i = ; i < allFontName.Length; i++ )
{
allFontName[i] = "";
}
writefileinfo = "字体名称、字号文件(fontsizeinfo.txt)写入状态:空闲状态";
prefabFontSizeInfoSaveDir = "dir name"; } void InitData()
{
ID = -;
// 待替换字体
previousFont = null;
previourFontSelectInfo = "";
// 新字体
newFont = null;
newFontSelectInfo = "";
// 字体对应文件
fontSizeFilePath = "file name";
fontSizeFilePathSelectInfo = "";
// 保存字号对应文件
fontSizeArray.Clear();
// 新prefab保存目录
newPrefabSaveDir = "dir name"; objpath_test = "";
}
static void FontInit()
{
// 查找选中的prefab内的所有字体,以及字体所设置的所有字号 UnityEngine.Object[] selectObjs = Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.DeepAssets); foreach (UnityEngine.Object selectObj in selectObjs)
{
GameObject obj = null;
try
{
obj = (GameObject)selectObj;
}
catch
{
continue;
} if (obj == null || selectObj == null)
{
Debug.LogWarning("ERROR:Obj Is Null !!!");
continue;
}
string objPath = AssetDatabase.GetAssetPath(selectObj); if (objPath.Length < || objPath.EndsWith(".prefab") == false)
{
Debug.LogWarning("ERROR:Folder=" + objPath);
}
else
{
string prePath = objPath.Substring(, objPath.Length - ).Replace("\\", "/").ToLower(); allNeedReplacePrefab.Add(obj);
Debug.Log("Selected Folder=" + objPath); // 直接修改prefab
UILabel[] labels = obj.GetComponentsInChildren<UILabel>(true); foreach (UILabel label in labels)
{
// 保存字体 以及字号 if ( label.trueTypeFont == null )
{
Debug.Log("font is null" + prePath);
}
else
{
if (!allFonts.ContainsKey(label.trueTypeFont.name))
{
allFonts.Add(label.trueTypeFont.name, label.trueTypeFont);
}
if (allFontsSize.ContainsKey(label.trueTypeFont.name))
{
allFontsSize[label.trueTypeFont.name].Add(label.fontSize);
}
else
{
allFontsSize.Add(label.trueTypeFont.name, new HashSet<int>());
allFontsSize[label.trueTypeFont.name].Add(label.fontSize);
} if ( allFontNameSizePrefabName.ContainsKey( label.trueTypeFont.name))
{
if ( allFontNameSizePrefabName[label.trueTypeFont.name].ContainsKey(label.fontSize))
{
allFontNameSizePrefabName[label.trueTypeFont.name][label.fontSize].Add(objPath);
}
else
{
allFontNameSizePrefabName[label.trueTypeFont.name].Add(label.fontSize, new HashSet<string>());
allFontNameSizePrefabName[label.trueTypeFont.name][label.fontSize].Add(objPath);
}
}
else
{
allFontNameSizePrefabName.Add(label.trueTypeFont.name, new Dictionary<int, HashSet<string> >());
allFontNameSizePrefabName[label.trueTypeFont.name].Add(label.fontSize, new HashSet<string>());
allFontNameSizePrefabName[label.trueTypeFont.name][label.fontSize].Add(objPath);
}
}
}
UIPopupList[] poplists = obj.GetComponentsInChildren<UIPopupList>(true);
foreach (UIPopupList popListItem in poplists)
{
// 保存字体 以及字号
if (popListItem.trueTypeFont == null)
{
Debug.Log("font is null" + prePath);
}
else
{
if (!allFonts.ContainsKey(popListItem.trueTypeFont.name))
{
allFonts.Add(popListItem.trueTypeFont.name, popListItem.trueTypeFont);
}
if (allFontsSize.ContainsKey(popListItem.trueTypeFont.name))
{
allFontsSize[popListItem.trueTypeFont.name].Add(popListItem.fontSize);
}
else
{
allFontsSize.Add(popListItem.trueTypeFont.name, new HashSet<int>());
allFontsSize[popListItem.trueTypeFont.name].Add(popListItem.fontSize);
}
}
}
}
}
int i = ;
foreach ( KeyValuePair<string,Font> kv in allFonts)
{
allFontName[i] = kv.Key;
i++;
} if (prefabFontSizeInfoSaveDir.Equals("") || prefabFontSizeInfoSaveDir.Equals("dir name"))
{
Debug.LogWarning("未选择目录,不保存文字信息");
writefileinfo = "未选择文件保存目录,因此不保存字号信息 ";
}
else
{
writefileinfo = "字体名称、字号文件(fontsizeinfo.txt)写入状态:正在写入";
writefileinfo = WriteFontSizeInfoToFile(prefabFontSizeInfoSaveDir);
} } static string WriteFontSizeInfoToFile(string path)
{ FileStream fs = new FileStream( prefabFontSizeInfoSaveDir + "/fontsizeinfo.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
List<int> fontSizeList = new List<int>();
sw.WriteLine("字体信息如下,格式为:【 字体名称:所有字号 】 ");
// 输出信息
foreach (var item in allFontsSize)
{
sw.Write(item.Key + ":");
fontSizeList.Clear(); foreach (var fontsize in item.Value)
{
fontSizeList.Add(fontsize);
//sw.Write(fontsize + " ");
}
fontSizeList.Sort(); foreach (var fontsizeInList in fontSizeList)
{
sw.Write(fontsizeInList + ",");
}
sw.WriteLine();
}
foreach (KeyValuePair<string, Dictionary<int,HashSet<string> > > allItemInfo in allFontNameSizePrefabName)
{
sw.WriteLine();
sw.Write("字体名称(fontName) :" + allItemInfo.Key +"," + "所有字号个数(allFontSizeCount):" + allItemInfo.Value.Count);
sw.WriteLine(); List<KeyValuePair<int,HashSet<string> > > lst = new List<KeyValuePair<int,HashSet<string>>>(allItemInfo.Value);
lst.Sort(delegate(KeyValuePair<int, HashSet<string>> s1, KeyValuePair<int, HashSet<string>> s2)
{
return s1.Key.CompareTo(s2.Key);
}); foreach (var fontSizeAndPrefabName in lst)
{
sw.WriteLine();
sw.WriteLine("--字号(fontSize) : " + fontSizeAndPrefabName.Key + " : ");
foreach (var prefabName in fontSizeAndPrefabName.Value)
{
sw.WriteLine(" " + prefabName + ";");
}
}
} sw.Flush();
sw.Close();
fs.Close();
return "字体名称、字号文件(fontsizeinfo.txt)写入状态:保存成功";
} /// <summary> 保存.</summary>
void OnSelectNewFont(UnityEngine.Object obj)
{
newFont = obj as Font;
//NGUISettings.ambigiousFont = obj;
Repaint();
} void OnSelectPreviousFont(UnityEngine.Object obj)
{
previousFont = obj as Font;
//NGUISettings.ambigiousFont = obj;
Repaint();
}
void OnSelectAtlas(UnityEngine.Object obj)
{
NGUISettings.atlas = obj as UIAtlas;
Repaint();
}
/// <summary> 刷新窗口. </summary>
void OnSelectionChange() { Repaint(); } public static bool IsSetNullFont; /// <summary>UI绘制区域.</summary>
void OnGUI()
{
try
{
int startWidth = ;
int startHeight =;
EditorGUIUtility.labelWidth = 100f; int _LineStartWidth = startWidth;
int _LineStartHeight = startHeight; EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), "1、选择Prefab内字体名称、字号信息文件保存目录(文件名默认为fontsizeinfo.txt)", EditorStyles.boldLabel); _LineStartWidth = startWidth + ;
_LineStartHeight += ;
newPrefabSaveDir = EditorGUI.TextArea(new Rect(_LineStartWidth, _LineStartHeight, , ), prefabFontSizeInfoSaveDir, EditorStyles.textField);
_LineStartWidth += ;
if (GUI.Button(new Rect(_LineStartWidth, _LineStartHeight, , ), "选择目录"))
{
prefabFontSizeInfoSaveDir = EditorUtility.SaveFolderPanel("Save newPrefab to directory", "./", "");
}
_LineStartWidth = startWidth;
_LineStartHeight += ; EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), "2、点击按钮获取字体信息(若第1步未选择目录,则不保存文件)", EditorStyles.boldLabel); _LineStartWidth = startWidth + ;
_LineStartHeight += ; if (GUI.Button(new Rect(_LineStartWidth , _LineStartHeight, , ), "获取所选Prefab内字体信息并将信息写入文件"))
{
FontInit();
}
_LineStartWidth = startWidth + ;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), writefileinfo, EditorStyles.boldLabel); _LineStartWidth = startWidth;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), "3、选择需要替换的字体", EditorStyles.boldLabel); _LineStartWidth = startWidth + ;
_LineStartHeight += ; ID = EditorGUI.Popup(new Rect(_LineStartWidth, _LineStartHeight, , ), ID, allFontName);
if (ID >= )
{
previousFont = allFonts[allFontName[ID]];
} _LineStartWidth += ;
//EditorGUI.TextArea(new Rect(_LineStartWidth, _LineStartHeight, 300, 20), prefabFontSizeInfoSaveDir, EditorStyles.textField);
EditorGUI.ObjectField(new Rect(_LineStartWidth, _LineStartHeight, , ), previousFont, typeof(Font), false);
_LineStartWidth += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), previourFontSelectInfo, EditorStyles.boldLabel);
/***
_LineStartWidth = startWidth + 40;
_LineStartHeight += 40; GUILayout.BeginHorizontal(); if (GUI.Button(new Rect(_LineStartWidth, _LineStartHeight, 80, 20), "Font ▽"))
{
ComponentSelector.Show<Font>(OnSelectPreviousFont);
}
_LineStartWidth += 90;
previousFont = EditorGUI.ObjectField(new Rect(_LineStartWidth, _LineStartHeight, 200, 20), previousFont, typeof(Font), false) as Font;
_LineStartWidth += 210;
if (previousFont != null && GUI.Button(new Rect(_LineStartWidth, _LineStartHeight, 20, 20), "X"))
{
previousFont = null;
}
GUILayout.EndHorizontal();
**/
_LineStartWidth = startWidth;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(startWidth, _LineStartHeight, , ), "4、选择新字体(如不选择新字体,则Prefab内字体将置空)", EditorStyles.boldLabel); _LineStartWidth = startWidth;
_LineStartHeight += ;
GUILayout.BeginHorizontal();
_LineStartWidth = startWidth + ;
if (GUI.Button(new Rect(_LineStartWidth, _LineStartHeight, , ), "Font ▽"))
{
ComponentSelector.Show<Font>(OnSelectNewFont);
}
_LineStartWidth += ;
newFont = EditorGUI.ObjectField(new Rect(_LineStartWidth, _LineStartHeight, , ), newFont, typeof(Font), false) as Font;
_LineStartWidth += ;
if (newFont != null && GUI.Button(new Rect(_LineStartWidth, _LineStartHeight, , ), "X"))
{
newFont = null;
}
_LineStartWidth += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), newFontSelectInfo, EditorStyles.boldLabel);
GUILayout.EndHorizontal(); _LineStartWidth = startWidth;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), "5、选择字号对应文件(不选择文件,则字号不变)", EditorStyles.boldLabel); _LineStartWidth = startWidth + ;
_LineStartHeight += ;
//Rect textRect = new Rect(_LineStartWidth, _LineStartHeight, 300, 150);
fontSizeFilePath = EditorGUI.TextArea(new Rect(_LineStartWidth, _LineStartHeight, , ), fontSizeFilePath, EditorStyles.textField);
_LineStartWidth += ; if (GUI.Button(new Rect(_LineStartWidth, _LineStartHeight, , ), "打开文件"))
{
fontSizeFilePath = EditorUtility.OpenFilePanel("Open file directory", "./", "txt");
}
_LineStartWidth = startWidth + ;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), fontSizeFilePathSelectInfo, EditorStyles.boldLabel); _LineStartWidth = startWidth + ;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), "字号对应文件格式为:序号,老字号,新字号", EditorStyles.boldLabel); _LineStartWidth = startWidth + ;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), "示例:", EditorStyles.boldLabel);
_LineStartWidth += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), "1,20,30", EditorStyles.boldLabel);
_LineStartWidth = startWidth + ;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), "2,25,40", EditorStyles.boldLabel); _LineStartWidth = startWidth + ;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, , ), "3,18,28", EditorStyles.boldLabel); //_LineStartWidth = startWidth;
//_LineStartHeight += 30; //EditorGUI.LabelField(new Rect(_LineStartWidth, _LineStartHeight, 150, 150), "选择新Prefab保存目录", EditorStyles.boldLabel); //_LineStartWidth = startWidth;
//_LineStartHeight += 20;
//newPrefabSaveDir = EditorGUI.TextArea(new Rect(_LineStartWidth, _LineStartHeight, 300, 20), newPrefabSaveDir, EditorStyles.textField);
//_LineStartWidth += 310;
//if (GUI.Button(new Rect(_LineStartWidth, _LineStartHeight, 80, 18), "选择目录"))
//{
// newPrefabSaveDir = EditorUtility.SaveFolderPanel("Save newPrefab to directory", "./", "");
//} _LineStartWidth = startWidth;
_LineStartHeight += ;
EditorGUI.LabelField(new Rect(startWidth, _LineStartHeight, , ), "6、点击按钮替换文字信息", EditorStyles.boldLabel); _LineStartWidth = startWidth + ;
_LineStartHeight += ; if (GUI.Button( new Rect(_LineStartWidth , _LineStartHeight,, ),"开始替换"))
{
ReplaceFontAndFontSize();
}
}
catch (System.Exception ex)
{
Debug.LogError(ex.Message + objpath_test);
previousFont = null;
newFont = null;
fontSizeFilePath = "file name"; }
} private void ReplaceFontAndFontSize()
{
if (previousFont == null)
{
previourFontSelectInfo = "未选择需要替换的字体,请选择...";
Debug.LogError(previourFontSelectInfo);
return;
} if (newFont == null)
{
newFontSelectInfo = "未选择新字体,字体将置空";
Debug.LogWarning(newFontSelectInfo);
} if (fontSizeFilePath.Equals("") || fontSizeFilePath.Equals("file name"))
{
fontSizeFilePathSelectInfo = "你没有选择对应字号文件,将不替换字号 ";
Debug.LogWarning(fontSizeFilePathSelectInfo);
CorrectionPublicFont( newFont, previousFont, false);
}
else
{
//读取文件内容
StreamReader sr = new StreamReader(fontSizeFilePath, Encoding.Default); string strLine = null;
fontSizeArray.Clear();
while ((strLine = sr.ReadLine()) != null)
{
if (!string.IsNullOrEmpty(strLine))
{
string[] newArray = strLine.Split(',');
fontSizeArray.Add(newArray);
} }
sr.Close();
// 具体替换
CorrectionPublicFont(newFont, previousFont, true);
}
StaticInitData();
InitData();
} private void CorrectionPublicFont(Font replace, Font matching, bool isReplaceFontSize)
{
foreach (GameObject obj in allNeedReplacePrefab)
{
// 直接修改prefab
UILabel[] labels = obj.GetComponentsInChildren<UILabel>(true);
int newFontSize = ;
foreach (UILabel label in labels)
{
if (label.trueTypeFont == matching)
{
label.trueTypeFont = replace;
newFontSize = GetNewFontSizeByOldSize(label.fontSize);
label.fontSize = newFontSize;
}
}
UIPopupList[] poplists = obj.GetComponentsInChildren<UIPopupList>(true);
foreach (UIPopupList popListItem in poplists)
{
if (popListItem.trueTypeFont == matching)
{
// NGUISettings.ambigiousFont = replace;
popListItem.trueTypeFont = replace;
newFontSize = GetNewFontSizeByOldSize(popListItem.fontSize);
popListItem.fontSize = newFontSize;
}
}
EditorUtility.SetDirty(obj);
/**** 创建新prefab 失败 ******/
/****
GameObject clone = GameObject.Instantiate(obj) as GameObject;
UILabel[] labels = clone.GetComponentsInChildren<UILabel>(true);
int newFontSize = 0;
foreach (UILabel label in labels)
{
if (label.trueTypeFont == matching)
{
label.trueTypeFont = replace;
newFontSize = GetNewFontSizeByOldSize(label.fontSize);
label.fontSize = newFontSize;
}
}
UIPopupList[] poplists = clone.GetComponentsInChildren<UIPopupList>(true);
foreach (UIPopupList popListItem in poplists)
{
if (popListItem.trueTypeFont == matching)
{
// NGUISettings.ambigiousFont = replace;
popListItem.trueTypeFont = replace;
newFontSize = GetNewFontSizeByOldSize(popListItem.fontSize);
popListItem.fontSize = newFontSize;
}
}
SaveDealFinishPrefab(clone, path);
GameObject.DestroyImmediate(clone);
******/
Debug.Log("Connect Font Success=" + obj.name); }
EditorApplication.SaveAssets();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
private int GetNewFontSizeByOldSize(int fontSize)
{
int newFontSize = fontSize;
if (fontSizeArray.Count > )
{
int nRow = fontSizeArray.Count;
int nCol = ((string[])fontSizeArray[]).Length;
for ( int i = ; i < nRow; i++ )
{
string[] data = (string[])fontSizeArray[i];
for (int j = ; j < nCol;j++ )
{
if (fontSize == int.Parse(data[]))
{
newFontSize = int.Parse(data[]);
return newFontSize;
}
} }
}
return newFontSize;
}
//private void SaveDealFinishPrefab(GameObject go, string path)
//{
// if (File.Exists(path) == true)
// {
// UnityEngine.Object prefab = AssetDatabase.LoadAssetAtPath(path, typeof(GameObject));
// PrefabUtility.ReplacePrefab(go, prefab);
// }
// else
// {
// PrefabUtility.CreatePrefab(path, go);
// }
//}
}

直接复制到代码内,然后放在Editor下,就可以用辣

至于步骤,在界面上说的也很清楚了。不明白的,怪自己智商咯。