让世界跨越语言边界: 一种面向 VRChat 世界创作的可扩展本地化框架 —— I18n
VRChat 作为一个全球性的社交平台,其用户来自世界各地,可能倾向于使用不同的语言。目前,VRChat 客户端中一共提供了 16 种语言支持。因此,在创作世界的过程中,如果你希望你的世界能够被更多用户访问和理解,为你的世界提供多语言支持就非常重要。
本框架提供了一种实现多语言支持的方式。你可以为你的世界提供不同语言的文本内容,并根据用户客户端的语言设置自动切换显示的文本。此外,本框架还提供了一个可扩展的框架,允许你 扩展 支持更多本地化 语言文件格式 和 本地化游戏物件。
接下来的章节将介绍如何使用这个框架实现多语言支持,以及如何扩展它以满足你的特定需求。
目前支持的语言文件格式:
Portable Object (.po)格式: 这是一种常见的本地化文件格式,广泛用于各种软件和游戏中。它使用简单的文本格式存储原始文本和翻译文本,并支持注释和上下文信息。
目前支持的本地化游戏物件:
TextMeshProUGUI: 这是 Unity 中常用的文本组件,广泛用于 UI 中。通过使用本框架,你可以轻松为其提供多语言支持,并根据用户的语言设置自动切换显示的文本内容。
安装
- 下载
Xuan25-VRC-Common-Utilities组件包,并将其导入到你的 Unity 项目中。你可以使用 Git 将其clone到项目的 Packages 目录下,或者直接下载压缩包并将其解压到该目录中。 - 在 Unity 项目中,找到
Packages/Xuan25 Common Utilities/Internationalization/Examples目录下的示例场景Examples.unity,并将其打开。你可以在该场景中查看和测试框架的使用方法。
使用方法
在详细阐述使用方法之前,以下是构成这个框架的几个关键部分:
- 本地化句柄: 指用于引用和管理本地化资源的标识符。在这个组件中,对应于任意继承或实现
LocaleHandle的类。- PortableObject 本地化句柄: 指专门用于处理
.po文件的 本地化句柄 实现。它负责解析.po文件,并提供接口来获取翻译文本。
- PortableObject 本地化句柄: 指专门用于处理
- 组件本地化: 指将游戏组件与本地化关联起来,以便根据用户的语言设置自动对组件进行本地化处理。在这个组件中,对应于任意继承或实现
ComponentLocale的类。- TextMeshProUGUI 本地化: 指专门用于处理
TextMeshProUGUI组件的 组件本地化 实现。它负责根据用户的语言设置自动切换TextMeshProUGUI组件显示的文本内容。
- TextMeshProUGUI 本地化: 指专门用于处理
- 本地化管理器: 指负责加载、管理和提供本地化资源的系统组件。它协调 本地化句柄 和 组件本地化 之间的交互。相关的 本地化句柄 和 组件本地化 实现需要注册到 本地化管理器 中,并由它进行管理和协调。一个世界中需要有 至少 一个 本地化管理器 实例。
基础用法
- 在场景中创建一个空物件,并将
LocaleManager组件添加到该物件上。这个物件将作为 本地化管理器,负责管理和协调本地化资源。 - 创建一个
TextMeshProUGUI文本物件,并将TextMeshProUGUILocale组件添加到该物件上。这是针对TextMeshProUGUI组件的 组件本地化 实现,它会根据用户的语言设置自动切换显示的文本内容。你不需要设置TextMeshProUGUILocale组件的Text Component属性,因为它会自动获取同一物件上的TextMeshProUGUI组件。 - 设置
TextMeshProUGUILocale组件的Manager属性,选择前一步创建的 本地化管理器 物件。 - 为这个
TextMeshProUGUILocale组件指定一个唯一的文本 ID,例如 "welcome_message"。这个 ID 将用于在本地化资源中引用对应的文本内容。将这个 ID 设置到TextMeshProUGUILocale组件的Text ID属性中,或填写到TextMeshProUGUI组件的Text属性中,两者选其一即可。 - 创建多个不同语言的
.po.txt文件。受限于架构设计,扩展名应为.po.txt,而不是常见的.po。在这些文件中,为 "welcome_message" 这个文本 ID 提供不同语言的翻译文本。例如,在en.po.txt文件中提供英文翻译,在zh-CN.po.txt文件中提供简体中文翻译。 - 为每个
.po.txt文件在场景中创建一个带有PortableObjectHandle组件的新物件,并将对应的.po.txt文件设置到PortableObjectHandle组件的Portable Object File属性上。这个组件是针对.po文件的 本地化句柄 实现,它将解析.po文件并提供接口来获取翻译文本。 - 如果
.po.txt文件头中包含声明本地化语言的头部信息,则可以设置PortableObjectHandle的Locale Header Key属性,组件会自动识别该文件对应的语言。否则,你需要手动设置PortableObjectHandle组件的Locale Override属性来指定该文件对应的语言。 - 设置
PortableObjectHandle组件的Manager属性,选择前面创建的 本地化管理器 物件,以便将这个 本地化句柄 注册到 本地化管理器 中进行管理。
在完成上述步骤后,你的场景层级结构可能如下所示:
Scene
├── LocaleManager # 本地化管理器
│ ├── en # PortableObjectHandle,绑定 en.po.txt
│ └── zh-CN # PortableObjectHandle,绑定 zh-CN.po.txt
└── Canvas
└── WelcomeText # TextMeshProUGUI,挂载 TextMeshProUGUILocale
en.po.txt 文件内容示例:
# 示例 en.po.txt 文件内容
msgid ""
msgstr ""
"Language: en\n"
msgid "welcome_message"
msgstr "Welcome to our world!"
zh-CN.po.txt 文件内容示例:
# 示例 zh-CN.po.txt 文件内容
msgid ""
msgstr ""
"Language: zh-CN\n"
msgid "welcome_message"
msgstr "欢迎来到我们的世界!"
运行场景后,你应该能够看到 TextMeshProUGUI 文本物件根据用户客户端的语言设置,自动切换显示不同语言的文本内容。
进阶用法
多本地化管理器
对于更复杂的场景,你可能希望将整个世界拆分为不同的功能组件,或者为特定的可复用组件、Prefab 或 Package 提供本地化支持,并为每个组件提供独立的本地化资源和管理。这时,你可以在每个组件中创建一个 本地化管理器 实例,并将相关的 本地化句柄 和 组件本地化 注册到对应的 本地化管理器 中进行管理。
这样可以实现更细粒度的本地化资源管理,并有助于组织和维护大量本地化资源。
文本模板
在一些情况下,你可能希望在文本内容中包含一些动态变化的变量,例如玩家的名字、分数、时间等。这时,你可以在文本内容中使用占位符表示这些变量,并在运行时通过代码替换这些占位符,生成最终显示的文本内容。
本组件使用 C# 的格式化字符串语法来实现文本模板功能,因此你可以在文本内容中使用 {0}、{1}、{2} 等格式来表示变量,例如 你好, {0}! 我是 {1}。,并设置 TextMeshProUGUILocale 组件的 Variables 属性来提供这些变量的值。当语言被设置时,组件会在运行时将这些占位符替换为对应的变量值,并生成最终显示的文本内容。
你也可以通过调用 Reload 方法手动触发文本内容更新,以便在变量值发生变化时及时更新显示内容。
PortableObject 列表管理
如果你的项目中有大量的 .po 文件需要被包装成 PortableObjectHandle 组件进行管理,你可以在场景中添加一个带 PortableObjectList 的物件,这个组件允许你管理一个 PortableObject 文件列表,并帮助你批量生成和配置 PortableObjectHandle 组件。
运行时动态加载和注册
在某些场景下,你可能希望从网络或其他外部来源动态加载本地化资源,以便在运行时更新文本内容、支持用户生成的翻译,或者动态创建新的需要被本地化的组件。这时,你可以通过编写 Udon 程序,在运行时创建和注册 本地化句柄 或 组件本地化,并调用 本地化管理器 提供的 RegisterLocaleHandle 或 RegisterComponentLocale 方法来注册它们,以便将它们纳入本地化系统的管理和协调中。
相应地,你也可以通过调用 本地化管理器 的 UnregisterLocaleHandle 或 UnregisterComponentLocale 方法来注销不再需要的 本地化句柄 或 组件本地化,以便将它们从本地化系统中移除。
本地化句柄烘焙与优化
要注意的是,虽然框架允许在运行时对 本地化句柄 进行动态的加载和注册,但其相对于在构建中存在的 本地化句柄 来说,其性能可能会更低。这是由于框架会在构建的时候对项目中的 本地化句柄 进行烘焙,以提高运行时的冷启动速度和性能。因此,如果你知道在构建时就已经确定了需要使用的本地化资源,建议将它们在构建时注册到 本地化管理器 中,以便在运行时能够更高效地访问和使用这些资源。
扩展组件
如果你的项目需要 PortableObject 本地化文件或 TextMeshProUGUI 本地化组件等已提供支持的以外的其他类型的本地化资源或组件,你也可以通过实现新的 本地化句柄 或 组件本地化 来 扩展 这个框架,以满足你的特定需求。
任何实现了 LocaleHandle 和 ComponentLocale 的类,都可以通过注册到 本地化管理器 中,纳入本地化系统的管理和协调。
No comments to display
No comments to display