专栏首页游戏开发之旅我使用的Unity开发多语言处理方案

我使用的Unity开发多语言处理方案

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/CJB_King/article/details/100513905

最近开发的项目要求进行多语言处理,我使用的Unity开发多语言处理具体方案就是,在目标Text添加监听事件以及对应的目标语言文案,当语言改变时触发事件,在语言库中查找对应的文案,进行显示,查找方法我用的是C#的反射原理,下面上代码说明。

定义数据Model

[System.Serializable]
public class LanguageType
{
    public string LanguageName;
    public LanguageInfo languageData;
}
[CreateAssetMenu(menuName = "Configure/LanguageConfigure")]
public class LanguageConfigure : ScriptableObject
{

    public LanguageType[] languages;

}

脚本写好后,回到Project目录,选择文件夹,右键“Create->Configure/LanguageConfigure",创建资源文件作为要本地化的语言库,如下所示:

上面的文库填完之后可以直接拿来使用,也可以使用JSON转化工具将其转为JSON文本文件使用,我这里使用的是转为JSON使用的;

序列化类转化JSON文本文件工具

public class HelperTool {

    [MenuItem("Tools/FileToJsonFile")]
    public static void SwitchToJson()
	{
        Object[] selectedObjs = Selection.GetFiltered(typeof(ScriptableObject), SelectionMode.DeepAssets);
         
        for (int i=0;i<selectedObjs.Length;i++)
        {
            string rootPath =Application.dataPath+"/Resources/Config/";
            Debug.Log(selectedObjs[i].GetType().Name);
            string path = rootPath+selectedObjs[i].name+".txt";
            string jsonInfo = JsonUtility.ToJson(selectedObjs[i]);
            using (FileStream stream = File.Create(path))
            {
                byte[] array = System.Text.Encoding.UTF8.GetBytes(jsonInfo);
                stream.Write(array, 0, array.Length);
                AssetDatabase.Refresh();
            }
        }
	}
}

语言管理类

[System.Serializable]
public class LanguageData 
{

    public LanguageType[] languages;

}
public class LanguageManager : MonoBehaviour
{
    private static LanguageManager _mgr = null;
    public static LanguageManager _instance
    {
        get
        {
            if(_mgr==null)
            {
                GameObject LanguageManager = new GameObject("LanguageManager");
                _mgr = LanguageManager.AddComponent<LanguageManager>();
                DontDestroyOnLoad(LanguageManager);
            }
            return _mgr;
        }
    }


    public delegate void LanguageChanged(string langunagName);
    public event LanguageChanged OnLanguageChangedEvent;

    private List<LanguageType> LanguageDic;
    private LanguageInfo CurrentLanguage;
    private void Awake()
    {
        _mgr = this;
        InitLanguageResource();
      
    }
    private void Start()
    {
        ChangeLanguage(PlayerPrefs.GetString(PlayerPrefsManager.LANGUAGE));    //

    }
    void InitLanguageResource()
    {
        TextAsset txtLanguage= Resources.Load<TextAsset>("Config/LanguageConfigure");
        LanguageData languageConfigure = JsonUtility.FromJson<LanguageData>(txtLanguage.text);
        LanguageDic =new List<LanguageType>(languageConfigure.languages);

    }
    public void ChangeLanguage(string LanguageKey)
    {
        if(string.IsNullOrEmpty(LanguageKey))
        {
            LanguageKey = "En";
        }
        PlayerPrefs.SetString(PlayerPrefsManager.LANGUAGE, LanguageKey);
        for (int i=0;i< LanguageDic.Count;i++)
        {
            if(LanguageDic[i].LanguageName== LanguageKey)
            {
                CurrentLanguage = LanguageDic[i].languageData;
                if(OnLanguageChangedEvent!=null)
                OnLanguageChangedEvent(LanguageKey);
            }
        }
       
        
    }
    public string GetLangeageByKey(string key)
    {
        FieldInfo[] fieldInfos = CurrentLanguage.GetType().GetFields();
        for (int i=0;i< fieldInfos.Length;i++)
        {
            if (fieldInfos[i].Name == key)
            {
                return (string)fieldInfos[i].GetValue(CurrentLanguage);
            }
        }
        return null;
    }
   
}

本地化的Text监听

public class LanguageSetListener : MonoBehaviour
{
    public string key;
    public Font font;
    private Font defaultFont;
    string Lkey;
    void Awake()
    {
       
        defaultFont = this.GetComponent<Text>().font;
    }
    private void Start()
    {
        LanguageManager._instance.OnLanguageChangedEvent += UpdateLanguage;

        Lkey = PlayerPrefs.GetString(PlayerPrefsManager.LANGUAGE);
        if (!string.IsNullOrEmpty(Lkey))
        {
            LanguageManager._instance.ChangeLanguage(Lkey);
        }
    }
    private void OnDestroy()
    {
        LanguageManager._instance.OnLanguageChangedEvent -= UpdateLanguage;

    }
    void UpdateLanguage(string LanguageName)
    {
        string value = LanguageManager._instance.GetLangeageByKey(key);
        if(LanguageName.Equals("Ch")&&font!=null)
        {
            this.GetComponent<Text>().font = this.font;
        }
        else
        {
            this.GetComponent<Text>().font = defaultFont;
        }
        this.GetComponent<Text>().text = value;
    }
}

以上是我在项目中使用到的,基于项目特俗要求以及结构所限,写的有点麻烦,不过还是可以使用的,朋友们如果有其他解决方案,欢迎留言分享哦!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Unity游戏开发Photon Server之客户端架构

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    bering
  • Unity使用AssetImporter整理资源对其进行打包

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    bering
  • 设计模式之简单工厂模式

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明...

    bering
  • Json的序列化与反序列化以及乱入的k_BackingField

      今天需要使用Json数据,所以用到了Json的序列化与反序列化。首先先来说怎么序列化的: 1.序列化与反序列化   首先添加System.Runtime.S...

    hbbliyong
  • WCF学习笔记 2

    在学习WCF的ABCB之前,我们先创建一个NetNamedPipeBinding绑定方式的服务。

    小蜜蜂
  • 游戏设计模式——Unity事件队列(纪念京阿尼事件)

    在游戏开发过程中,经常会出现不同板块之间的信息交流,或是存在“当...,就...”的情况,事件队列编程模式可以有效解决消息传递中产生的脚本耦合问题,让同一个板块...

    汐夜koshio
  • C#笔记:反射的简单用法

    反射其实说白了就是,当你知道类的名字和位置。你可以在程序运行时直接创建实例调用它。没什么大不了的。

    超级大猪
  • 蚂蚁区块链第16课 JS SDK数据模型(账户|合约|交易|收据|日志|区块)

    本文讲解蚂蚁区块链合约平台 JS SDK 涉及的数据模型,包括账户模型,合约模型,交易模型,收据模型,日志模型,区块模型。

    辉哥
  • APK安装流程详解1——有关"安装ing"的实体类概述

    该类包含了从AndroidManifest.xml文件中收集的所有信息。 PackageInfo.java源码地址 通过源码我们知道PackageInfo是...

    隔壁老李头
  • AgileRepository - 一个基于接口的Repository快速开发库

    这是一个可以帮助你快速开发Repository的lib。有点像SpringData JPA根据方法名、注解来自动生成查询方法的功能。 对于一些简单的查询,只需...

    kklldog

扫码关注云+社区

领取腾讯云代金券