UGUI 文本多语言方案

栏目: 后端 · 发布时间: 6年前

内容简介:这是侑虎科技第457篇文章,感谢作者林健供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群465082844)作者主页:作者也是U Sparkle活动参与者,UWA欢迎更多开发朋友加入U Sparkle开发者计划,这个舞台有你更精彩!

这是侑虎科技第457篇文章,感谢作者林健供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群465082844)

作者主页: https://zhuanlan.zhihu.com/p/43374662

作者也是U Sparkle活动参与者,UWA欢迎更多开发朋友加入U Sparkle开发者计划,这个舞台有你更精彩!

前言

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

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

我们的需求

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

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

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

调研

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

Unity3D UGUI多语言

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

Unity3D实现多语言本地化

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

Unity UGUI 本地化方案

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

Unity国际化多语言设置

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

AssetStore 上的方案:I2 Localization

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

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

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

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

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

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

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

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

具体实现

1.添加组件

UGUI 文本多语言方案

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

UGUI 文本多语言方案

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

UGUI 文本多语言方案

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

UGUI 文本多语言方案

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

UGUI 文本多语言方案

以下为原理:

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版本。

文末,再次感谢林健的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:465082844)。

也欢迎大家来积极参与U Sparkle开发者计划,简称"US",代表你和我,代表UWA和开发者在一起!


以上所述就是小编给大家介绍的《UGUI 文本多语言方案》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

零边际成本社会

零边际成本社会

[美]杰里米·里夫金 / 赛迪研究院专家组 / 中信出版社 / 2014-11-1 / 49.00

在这本书中,《第三次工业革命》作者杰里米•里夫金开创性地探讨了极致生产力、协同共享、产消者、生物圈生活方式等全新的概念,详细地描述了数以百万计的人生产和生活模式的转变。他认为,“产消者”正在以近乎零成本的方式制作并分享自己的信息、娱乐、绿色能源和3D打印产品。他们也通过社交媒体、租赁商、合作组织以极低或零成本的模式分享汽车、住房、服装和其他物品;学生更多地参与到基于零成本模式的开放式网络课程…… ......一起来看看 《零边际成本社会》 这本书的介绍吧!

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具