UGUI 文本多语言方案

转载https://zhuanlan.zhihu.com/p/43374662

前言

为了使全世界的玩家都能自由流畅的玩到游戏,游戏支持多国语言是一个常见的需求。游戏的多语言涉及到UI显示,声音,图片等等,而UI中文本的多语言处理是基础。

Unity引擎主流的两套UI框架中,NGUI默认实现了UI文本的多语言功能,而UGUI并没有原生实现。导致我们的项目从NGUI迁移到UGUI的过程中遇到了麻烦,本文介绍了目前UGUI框架下文本多语言的几种方案,以及我们的实现。

我们的需求

1.参考NGUI,使用一套key对应多套文本的方式,来实现多语言。

2.支持游戏内动态切换语言,切换语言后自动刷新UI显示。

3.使用简单、方便,不引入插件。

调研

调研了一些市面上现有的UGUI的多语言方案:

unity3d UGUI多语言 - YYRise - 博客园

原理:给Text绑定key,在程序开始时设置本地语言。 需附加额外脚本,无运行时动态切换语言功能。

Unity3D实现多语言本地化 - CSDN博客

原理和功能和上面的方案类似。

Unity UGUI 本地化方案 - Localiztion Tool

不需要附加新的脚本,基于原生的Text组件进行扩展,但无运行时动态切换语言。

Unity 国际化 多语言设置 - Sun‘刺眼的博客 - 博客园

基于NGUI的原理,通过附加脚本形式实现多语言,但无运行时动态切换语言。

AssetStore 上的方案:I2 Localization - Asset Store

功能强大,但是需要集成插件,较为臃肿,会增添使用的复杂度,收费。是否可以运行时动态切换语言未知,没有试用。

经过调研,我认为现有的方案,并不能完全满足我的需求。大多要添加额外的组件脚本,或是无动态切换语言功能,不能切换字体,使用不够方便等等。

我的方案主要解决了几个痛点:

1.无需附加额外脚本进行文本的多语言。

2.支持运行时切换语言,并自动刷新多语言文本。

3.脚本上用预制体存储字体引用,多语言时替换不同字体只要替换几个预制体即可。而UGUI原生的方式是要替换项目中所有Text文件的字体属性。

4.增加菜单栏集成,创建多语言Text组件和原生Text是一致的,使用方便。

5.使用习惯和NGUI的多语言较为一致,无需插件,只需几个cs脚本即可。

 

具体实现

1.添加组件

 

2.设置字体和文本的key(这两项不能为空)

这里的Key_String,是沿用NGUI 里的多语言方案的形式,就是采用一个key对应多种语言文本的方式。下图中是对应的各个语言的文本及内容。

CustomFont 是也是参照NGUI的多语言方案的使用习惯,把实际的字体文件通过引用的方式存储为Prefab,这样将来替换不同语言的字体文件时,只需要替换少量的字体Prefab文件即可,而不是像UGUI官方原生的那样需要替换所有Text组件的font。Prefab如下图:

3.一个API实现切换语言动态刷新

以下为原理:

1.总体文本方案,是将NGUI的Localization脚本拿过来,用来加载文本源数据,然后Text基础上扩展了自定义组件,用于指定key,和字体,并用管理器通过注册事件形式,来实现统一的UI切换语言后的自动刷新。

思路总的来说,是借鉴了NGUI的那套多语言方案,经过改造成为UGUI的版本,解决了UGUI 字体替换麻烦,不能指定文本key,而且默认在切换字体后不能自动刷新的问题,这都是UGUI相比NGUI缺少的机制,这里进行了补全。中间很多东西参考了UGUI的源码,有些地方进行了重载,有些地方直接为了工具化使用,直接扒了少量代码。

2.扩展菜单实现:

public class LocalizationMenuExtension : MonoBehaviour {

    [MenuItem("GameObject/UI/Text_Local", false, 2000)]
    static public void AddText(MenuCommand menuCommand)
    {
        GameObject go = new GameObject("Text");
        LocalizationText txt = go.AddComponent<LocalizationText>();
        PlaceUIElementRoot(go, menuCommand);
        LocalizationManager.InitValue(txt);
    }
   //... 有省略,上面只放最核心部分
}

3.扩展Inspectors

[CustomEditor(typeof(LocalizationText))]
public class LocalizationTextEditor : UnityEditor.UI.TextEditor
{

    public override void OnInspectorGUI()
    {
        LocalizationText component = (LocalizationText)target;
        base.OnInspectorGUI();
        component.KeyString = EditorGUILayout.TextField("Key String", component.KeyString);
        component.CustomFont = (UIFontObj)EditorGUILayout.ObjectField("Custom Font", component.CustomFont, typeof(UIFontObj), true);
    }
}

4.扩展Text组件

using System;
using UnityEngine.UI;
using UnityEngine;
/// <summary>
/// Custom Text Control used for localization text.
/// </summary>
[AddComponentMenu("UI/Text_Local", 10)]
public class LocalizationText : Text
{
    protected override void Awake()
    {
        base.Awake();
        LocalizationManager.InitValue(this);
        font = CustomFont.UseFont;
    }

    protected override void OnEnable()
    {
        base.OnEnable();
        LocalizationManager.OnLocalize += OnLocalize;  
    }
    protected override void OnDisable()
    {
        base.OnDisable();
        if (LocalizationManager.OnLocalize!=null)
        {
            LocalizationManager.OnLocalize -= OnLocalize;
        }
     
    }

    /// <summary>
    /// 文本的key
    /// </summary>
    public string KeyString;

    /// <summary>
    /// 自定义字体,方便后期替换
    /// </summary>
    public UIFont CustomFont;

    /// <summary>
    /// 重新本地化,用于游戏内切换语言时调用
    /// </summary>
    public void OnLocalize()
    {
        text = Localization.Get(KeyString);
    }

    #region Override Part
    public override string text
    {
        get
        {
            m_Text = Localization.Get(KeyString);
            return m_Text;
        }
        set
        {
            if (String.IsNullOrEmpty(value))
            {
                if (String.IsNullOrEmpty(m_Text))
                    return;
                m_Text = "";
                SetVerticesDirty();
            }
            else if (m_Text != value)
            {
                m_Text = value;
                SetVerticesDirty();
                SetLayoutDirty();
            }
        }
    }

    

    #endregion

}

附上demo和package,使用的是Unity2017.4.8f1版本。

lengyuye/MyUGUILocalization​github.com图标

 

编辑于 2018-09-28

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值