遍历Unity场景和Prefab,提取Text组件文字,并导出Json表。可将Json文本进行多语言翻译后,利用工具将内容替换回原场景或Prefab。
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class ChangeTextLanguageTool : MonoBehaviour
{
[ExecuteInEditMode]
[MenuItem("LanguageTool/一键提取Prefab中文字")]
private static void GetAllPrefab()
{
LoadPath(Application.dataPath);
}
static void LoadPath(string path)
{
TextData _temData = new TextData();
string genPath = path;
string[] filesPath = Directory.GetFiles(genPath, "*.prefab", SearchOption.AllDirectories);
for (int i = 0; i < filesPath.Length; i++)
{
PrefabData _tempPrefab = new PrefabData();
filesPath[i] = filesPath[i].Substring(filesPath[i].IndexOf("Assets"));
GameObject _prefab = AssetDatabase.LoadAssetAtPath(filesPath[i], typeof(GameObject)) as GameObject;
GameObject prefabGameobject = PrefabUtility.InstantiatePrefab(_prefab) as GameObject;
_tempPrefab.PrefabName = prefabGameobject.name;
Text[] _tempAllText = prefabGameobject.transform.GetComponentsInChildren<Text>(true);
for (int j = 0; j < _tempAllText.Length; j++)
{
if (!string.IsNullOrEmpty(_tempAllText[j].text))
{
TextItemData _tempItemdata = new TextItemData();
_tempItemdata._ObjName = _tempAllText[j].gameObject.name;
_tempItemdata._TextContext = _tempAllText[j].text;
_tempPrefab._PrefabData.Add(_tempItemdata);
}
}
if (_tempPrefab._PrefabData.Count > 0)
_temData.Data.Add(_tempPrefab);
Debug.Log("遍历完成===========" + prefabGameobject.name);
MonoBehaviour.DestroyImmediate(prefabGameobject);
}
string[] ScenePath = Directory.GetFiles(genPath, "*.unity", SearchOption.AllDirectories);
for (int i = 0; i < ScenePath.Length; i++)
{
PrefabData _tempPrefab = new PrefabData();
ScenePath[i] = ScenePath[i].Substring(ScenePath[i].IndexOf("Assets"));
Debug.Log(ScenePath[i]);
if (ScenePath[i].Contains("Live2D"))
continue;
_tempPrefab.PrefabName = ScenePath[i];
EditorSceneManager.OpenScene(ScenePath[i], OpenSceneMode.Single);
var _temp = Resources.FindObjectsOfTypeAll(typeof(Text)) as Text[];
//_temp.Select(data => data.gameObject.scene.isLoaded);
foreach (Text obj in _temp)
{
if(!obj.gameObject.scene.isLoaded)
continue;
//Debug.LogError(obj.text);
if (!string.IsNullOrEmpty(obj.text))
{
TextItemData _tempItemdata = new TextItemData();
_tempItemdata._ObjName = obj.gameObject.name;
_tempItemdata._TextContext = obj.text;
_tempPrefab._PrefabData.Add(_tempItemdata);
}
}
if (_tempPrefab._PrefabData.Count > 0)
_temData.Data.Add(_tempPrefab);
}
Save(_temData);
}
static void Save(TextData data)
{
string Path = Application.dataPath + "/LanguageTool.json";
/*if (!File.Exists(Path))
File.Create(Path);*/
string json = JsonUtility.ToJson(data);
File.WriteAllText(Path, json);
EditorUtility.DisplayDialog("成功", "Prefab文本提取处理成功", "确定");
}
static Dictionary<string, PrefabData> m_dicTextData = new Dictionary<string, PrefabData>();
[ExecuteInEditMode]
[MenuItem("LanguageTool/一键替换LanguageTool字体")]
static void ChangText()
{
TextAsset text = Resources.Load<TextAsset>("LanguageTool");
TextData _data = JsonUtility.FromJson<TextData>(text.text);
m_dicTextData = new Dictionary<string, PrefabData>();
foreach (var item in _data.Data)
{
m_dicTextData[item.PrefabName] = item;
}
/*ChangeLabelText(Application.dataPath + "/App");
ChangeLabelText(Application.dataPath + "/Cosmos");
ChangeLabelText(Application.dataPath + "/Scenes");*/
ChangeLabelText(Application.dataPath);
EditorUtility.DisplayDialog("成功", "替换成功", "确定");
}
static void ChangeLabelText(string path)
{
string genPath = path;
int m = 0;
string[] filesPath = Directory.GetFiles(genPath, "*.prefab", SearchOption.AllDirectories);
for (int i = 0; i < filesPath.Length; i++)
{
filesPath[i] = filesPath[i].Substring(filesPath[i].IndexOf("Assets"));
GameObject _prefab = AssetDatabase.LoadAssetAtPath(filesPath[i], typeof(GameObject)) as GameObject;
GameObject prefabGameobject = PrefabUtility.InstantiatePrefab(_prefab) as GameObject;
PrefabData _tempData = null;
if (m_dicTextData.ContainsKey(prefabGameobject.name))
{
_tempData = m_dicTextData[prefabGameobject.name];
}
Text[] _tempAllText = prefabGameobject.transform.GetComponentsInChildren<Text>(true);
for (int j = 0; j < _tempAllText.Length; j++)
{
if (!string.IsNullOrEmpty(_tempAllText[j].text))
{
if (null != _tempData && _tempData._PrefabData.Count > 0)
{
for (int z = 0; z < _tempData._PrefabData.Count; z++)
if (_tempData._PrefabData[z]._ObjName == _tempAllText[j].gameObject.name)
{
_tempAllText[j].text = _tempData._PrefabData[z]._TextContext;
_tempData._PrefabData.RemoveAt(z);
break;
}
}
}
}
PrefabUtility.SaveAsPrefabAsset(prefabGameobject, filesPath[i]);
Debug.Log("遍历完成===========" + prefabGameobject.name);
MonoBehaviour.DestroyImmediate(prefabGameobject);
AssetDatabase.SaveAssets();
}
string[] ScenePath = Directory.GetFiles(genPath, "*.unity", SearchOption.AllDirectories);
for (int i = 0; i < ScenePath.Length; i++)
{
ScenePath[i] = ScenePath[i].Substring(ScenePath[i].IndexOf("Assets"));
Debug.Log(ScenePath[i]);
if (ScenePath[i].Contains("Live2D"))
continue;
PrefabData _tempData = null;
if (m_dicTextData.ContainsKey(ScenePath[i]))
{
_tempData = m_dicTextData[ScenePath[i]];
}
Scene _tempScene = EditorSceneManager.OpenScene(ScenePath[i], OpenSceneMode.Single);
//foreach (Text obj in UnityEngine.Object.FindObjectsOfType(typeof(Text)))
var _temp = Resources.FindObjectsOfTypeAll(typeof(Text)) as Text[];
//_temp.Select(data => data.gameObject.scene.isLoaded);
foreach (Text obj in _temp)
{
if(!obj.gameObject.scene.isLoaded)
continue;
if (!string.IsNullOrEmpty(obj.text))
{
if (null != _tempData && _tempData._PrefabData.Count > 0)
{
for (int z = 0; z < _tempData._PrefabData.Count; z++)
if (_tempData._PrefabData[z]._ObjName == obj.gameObject.name)
{
obj.text = _tempData._PrefabData[z]._TextContext;
_tempData._PrefabData.RemoveAt(z);
break;
}
}
}
}
EditorSceneManager.SaveScene(_tempScene);
AssetDatabase.SaveAssets();
}
}
}
[Serializable]
public class TextData
{
public List<PrefabData> Data = new List<PrefabData>();
}
[Serializable]
public class PrefabData
{
public string PrefabName = string.Empty;
public List<TextItemData> _PrefabData = new List<TextItemData>();
}
[Serializable]
public class TextItemData
{
public string _ObjName = string.Empty;
public string _TextContext = string.Empty;
}