Unity多语言转换工具

说明

遍历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;
}

你可能感兴趣的:(Unity工具)