抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

写项目时遇到多语言的问题,之前也跟导师聊过项目内的多语言,稍微总结下

多语言的思路

介绍下多语言的两种做法思路,一种是组件运行时处理,一种是运行前生成多个预制体与多份代码进行保存

组件处理

需要一个key值对应各语言的文本表。

对于静态文本,将key存储到组件中,运行时读取文本表将key转为对应语言的文本。动态文本运行时直接将key转为对应语言的文本。

预制体

可以简单克隆多个预制体,根据路径区分对应语言的预制体,代码也是类似区分。

优缺点

预制体相比于组件处理:

优点:

  • 运行效率更高,内存占用更小

缺点:

  • 包体更大

  • 需要重启重新加载预设与代码,无法运行时切换

一般来说还是选择组件处理多,接下来讲的实现方法也是类似的。

具体实现

Localization包

可以直接使用Untiy官方的Localization包,对于要处理的组件点击右上角Localize,会自动添加组件,放入key值就可以了,静态文本可以不编写代码完成。

LocalizedText

因为感觉Localization配表各方面比较麻烦(打算和其他地方也在用的配表方法统一),所以就还是自己写了,也不是很难,主要是拓展了TextMeshPro,添加一个key值,实时转换的话自己写一个事件吧,其实Localization也是这么做的。

具体代码

using TMPro;
using TMPro.EditorUtilities;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

public class LocalizedText : TextMeshProUGUI
{
    public string key = "";
    private bool hasChanged = false;

    public override string text
    {
        get => base.text;
        set
        {
            setText(value);
        }
    }

    private void setText(string text)
    {
        base.text = text;
        if (!EditorApplication.isPlaying) return;
        hasChanged = true;
    }

    protected override void Awake()
    {
        base.Awake();
        if (!EditorApplication.isPlaying) return;
        if (!hasChanged)
        {
            text = LocalizationManager.Instance.GetLanguage(key);
            hasChanged = true;
        }
    }
}

[CustomEditor(typeof(LocalizedText), true), CanEditMultipleObjects]
public class LocalizedTextEditor : TMP_EditorPanelUI
{
    private SerializedProperty key;

    protected override void OnEnable()
    {
        base.OnEnable();
        key = serializedObject.FindProperty("key");
    }

    public override void OnInspectorGUI()
    {
        EditorGUI.BeginChangeCheck();
        EditorGUILayout.PropertyField(key, new GUIContent("Key"));
        if (EditorGUI.EndChangeCheck())
        {
            serializedObject.ApplyModifiedProperties();
        }
        base.OnInspectorGUI();
    }
}

LocalizedText实现

setText方法记录了组件运行时被代码更改的情况,这种情况下就不会进行首次的静态文本的转换,EditorApplication.isPlaying代表目前编辑器正在运行,只有运行时才会更改。

实时转换的话加个事件来重设文本即可。

Editor类

主要是在Inspector下添加窗口,注意serializedObject.ApplyModifiedProperties();会将在窗口更改的属性应用到你设置的property中。

评论