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 文本多语言方案》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

Blog Design Solutions

Blog Design Solutions

Richard Rutter、Andy Budd、Simon Collison、Chris J Davis、Michael Heilemann、Phil Sherry、David Powers、John Oxton / friendsofED / 2006-2-16 / USD 39.99

Blogging has moved rapidly from being a craze to become a core feature of the Internetfrom individuals sharing their thoughts with the world via online diaries, through fans talking about their favori......一起来看看 《Blog Design Solutions》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

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

正则表达式在线测试