【Unity 实用工具篇】| 游戏多语言解决方案,官方插件Localization 实现本地化及多种语言切换

- 前言
- 【Unity 实用工具篇】| 游戏多语言解决方案,官方插件Localization 实现本地化及多种语言切换
- 一、多语言本地化插件 Localization
- 1.1 介绍
- 1.2 效果展示
- 1.3 使用说明
- 二、 插件导入并配置
- 2.1 安装 Localization
- 2.2 全局配置
- 三、多语言映射表
- 3.1 创建多语言文本配置表
- 3.2 添加多语言文本配置表内容
- 3.3 静态文本
- 3.2 动态文本
- 四、资源多语言映射表
- 五、映射表 导入/导出 Excel 便于管理
- 5.1 导出Localization Table为CSV
- 5.2 修改Excel中并重新导入
- 六、Build
- 总结

前言
- Unity的多语言本地化是一个很实用的功能,它可以帮助游戏支持多种语言,让不同语言的玩家都能够更好地体验游戏。
- 而实现本地化的方案也有很多种,各个方案之间也各有优劣,后面也会对多个方案进行介绍学习。
- 本文就来介绍一个专门作用于多语言本地化的Unity官方插件:
Localization。 - 这个插件方便进行游戏的多语言本地化,让游戏支持多种语言,下面就来看看该插件的使用方法吧!
【Unity 实用工具篇】| 游戏多语言解决方案,官方插件Localization 实现本地化及多种语言切换
一、多语言本地化插件 Localization
1.1 介绍
Localization是Unity官方推出的本地化插件,它可以帮助开发者在Unity项目中实现多语言支持。
在Unity中,Localization的工作原理是创建多个表格来存储不同语言的不同字符串。
可以通过Localization Tables创建这些表格,表格可以建立不同资源之间的对应关系,一个key对应多个语言的资源。
通过使用Localization插件,开发者可以方便地设置和获取当前语言和当前语言地区,从而为游戏或应用程序提供多种语言的支持。
这对于那些需要面向不同地区和不同语言的用户发布游戏或应用程序的开发者来说是非常有用的。
1.2 效果展示

1.3 使用说明
官方文档:官方文档
本文使用的Localization版本为1.4.5,Unity引擎版本为2023.1.9。
后续插件可能会有更新,或者使用老版本的插件时功能使用上可能会有所不同,实际使用时按照自己的版本要求即可。
二、 插件导入并配置
2.1 安装 Localization
打开菜单栏 Window -> Package Manager ,在搜索框中搜索Localization 并进行安装即可。
要注意Packages选择Unity Registry,不然可能搜不到该插件哦。

2.2 全局配置
打开菜单栏 Edit -> Project Settings -> Localization -> Create,找到Localization,点击Create创建,并选择一个文件目录进行文件保存。

点击 Locale Generator 搜索zh和en添加中英文配置,第一次添加时会让我们选择一个文件夹目录保存。

Locale Generator 用于添加或移出语言,每添加一种语言也会生成对应的配置文件,然后可以修改默认语言为中文,如下图所示:

三、多语言映射表
3.1 创建多语言文本配置表
打开菜单栏 Window -> Asset Management -> Localization Tables ,点击New Table Collection创建表格。
该表格用于建立不同资源之间的对应关系,一个key对应多个语言的资源,可以选择创建文本表或者资源表。
这里我们选择文本表(String Table Collection)使用,写好表名后点击Create就可以创建了,然后选择一个路径目录进行保存。

经过上面几个配置后可以在我们前面保存文件的路径下看到相关的文件,这里最好是根据自己的情况选择合适的文件夹进行管理保存。

3.2 添加多语言文本配置表内容
此时在Localization Tables中添加多语言文本即可,配置内容主要是Key和对应多种语言的文本。
可通过Window -> Asset Management -> Localization Tables 打开该窗口。

实际项目中不一定将多语言内容全部写在一个配置表中,不同的文本内容也可以通过创建多个配置表进行填写,让不同的模块自己管理文本内容也是一个不错的选择。
3.3 静态文本
此时在场景中添加一个文本组件Text,然后在该组件右侧菜单处点击Localize,会自动添加一个Localize String Event组件。
(这里也可以手动在下面添加Localize String Event组件,不过还要手动配置该组件绑定的Text组件,稍微麻烦一些,功能都是一样的)

此时在该组件中的String Reference参数中选择之前配置的多语言文本配置表中的Key即可完成多语言的配置。

此时运行程序,可以看到该Text组件的文本内容已经变成我们配置多语言文本配置表中的Key对应的文本了。
通过Game视图右上角的语言选择可以切换语种,点击切换不同语言后,Game视图中的文本也会即时的跟着切换了。

这样我们的静态文本就可以通过这种方法来添加多语言文本配置表中的Key绑定多语言了。
也可以通过脚本控制语言的切换,测试代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Settings;
using UnityEngine.ResourceManagement.AsyncOperations;public class LanguageManager : MonoBehaviour
{AsyncOperationHandle m_InitializeOperation;private Locale _chineseLocale;private Locale _englishLocale;void Start(){// SelectedLocaleAsync will ensure that the locales have been initialized and a locale has been selected.m_InitializeOperation = LocalizationSettings.SelectedLocaleAsync;if (m_InitializeOperation.IsDone){InitializeCompleted(m_InitializeOperation);}else{m_InitializeOperation.Completed += InitializeCompleted;}}void InitializeCompleted(AsyncOperationHandle obj){var locales = LocalizationSettings.AvailableLocales.Locales;for (int i = 0; i < locales.Count; ++i){var locale = locales[i];if (locale.LocaleName == "Chinese (Simplified) (zh)"){_chineseLocale = locale;}else if (locale.LocaleName == "English (en)"){_englishLocale = locale;}}}public void SwitchChinese(){LocalizationSettings.Instance.SetSelectedLocale(_chineseLocale);}public void SwitchEnglish(){LocalizationSettings.Instance.SetSelectedLocale(_englishLocale);}
}
将该脚本挂载到场景中,并在场景中添加两个Button分别绑定切换中英文的方法即可。

上述脚本代码也可以换成下方这种,更简单粗暴的方法切换语言。
using UnityEngine;
using UnityEngine.Localization.Settings;public class LanguageManager : MonoBehaviour
{public void SwitchChinese(){LocalizationSettings.SelectedLocale = LocalizationSettings.AvailableLocales.Locales[0];}public void SwitchEnglish(){LocalizationSettings.SelectedLocale = LocalizationSettings.AvailableLocales.Locales[1];}
}
索引值为Localization 的配置项中的多种语言的顺序,如下方第一个语言为中文则索引为0。

3.2 动态文本
除了可以设置静态文本,也可以在代码中获取对应的文本并进行动态设置,下面看一下动态文本的设置方法。
设置动态文本的方法有很多种,可以看情况选择,具体原理可以在官方文档仔细查阅,这里就直接写几种方法的使用示例。
1.最简单粗暴的方法,直接动态读表赋值。
using UnityEngine;
using UnityEngine.Localization.Settings;
using UnityEngine.UI;public class TestLocalization : MonoBehaviour
{public Text text;void Start(){var loadingResult = LocalizationSettings.StringDatabase.GetTableEntry("UITestTable", "ui_Test");text.text = loadingResult.Entry.GetLocalizedString();}
}
GetTableEntry() 第一个参数为多语言配置表的名字,第二个参数为该表里面的Key。
通过方法传入多语言配置表的名字及对应多语言的Key即可完成动态文本赋值。
不过要注意的是字符串表可能不会立即可用,例如在本地化系统初始化期间或尚未加载表时。
为了保险起见,可以确保该多语言配置表被加载出之后再进行赋值,可以来看第二种方法的使用示例。
2.等待语言配置表初始化之后在赋值。
using System.Collections;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine;
using UnityEngine.Localization.Settings;
using UnityEngine.UI;public class TestLocalization : MonoBehaviour
{public Text text;void Start(){StartCoroutine(LoadStrings());}IEnumerator LoadStrings(){// A string table may not be immediately available such as during initialization of the localization system or when a table has not been loaded yet.var loadingOperation = LocalizationSettings.StringDatabase.GetTableAsync("UITestTable");yield return loadingOperation;if (loadingOperation.Status == AsyncOperationStatus.Succeeded){var stringTable = loadingOperation.Result;text.text = stringTable.GetEntry("ui_Test").GetLocalizedString();}else{Debug.LogError("Could not load String Table\n" + loadingOperation.OperationException.ToString());}}
}
3.初始化时获得该多语言配置表,事件动态更新文本。
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Tables;
using UnityEngine.UI;public class Demo : MonoBehaviour
{public Text Name;private LocalizedStringTable stringTable = new LocalizedStringTable { TableReference = "UITestTable" };void OnEnable(){stringTable.TableChanged += LoadStrings;}void OnDisable(){stringTable.TableChanged -= LoadStrings;}void LoadStrings(StringTable stringTable){Name.text = GetLocalizedString(stringTable, "ui_Test");}static string GetLocalizedString(StringTable table, string entryName){var entry = table.GetEntry(entryName);return entry.GetLocalizedString();}
}
以上几种方法都可以正常使用,根据实际需求选择合适的即可。
四、资源多语言映射表
除了上面说到的文本的本地化之外,Localization 还支持资源本地化,使用方法与配置文本的方法类似,下面来看一下。
打开菜单栏 Window -> Asset Management -> Localization Tables ,点击New Table Collection创建表格。
该表格用于建立不同资源之间的对应关系,一个key对应多个语言的资源,这里选择创建一个资源配置表(AssetsTable Collection),写好表名后点击Create就可以创建了,然后选择一个路径目录进行保存。

创建完之后与文本配置的处理方式一样,在表中添加Key以及资源的内容,测试示例如下:

然后在场景中添加一个Image组件,在右侧菜单点击Localize(或者自己添加组件),选择我们添加的资源配置表中的Key即可完成。

效果如下,可以使用方法控制切换语言,也可以通过右上角进行切换。

五、映射表 导入/导出 Excel 便于管理
当项目中的文本量比较多的时候,使用Localization Table的方法会有些难以操作不便于管理。
所以此时可以考虑将Localization Table导出为Excel表格对文本进行管理,Localization 是支持Table的导入和导出的,下面来看一下怎样操作。
5.1 导出Localization Table为CSV
打开Localization Tables,然后右键Localization Table,选择 Export -> CSV...导出。

选择一个文件目录进行保存,就可以看到导出的Excel表格内容了,就是Localization Table中的内容。

5.2 修改Excel中并重新导入
在导出的Excel表格中我们可以进行增删改查的操作对表格进行管理,这样比直接在Localization Table中管理要轻松的多。

修改完之后可以在导入Localization Table中,要注意的是修改完之后要改成UTF-8的编码格式再保存文件,不然导入之后中文会显示乱码。
如果不知道怎么直接保存为UTF-8的编码格式,可以使用Notepad++等工具转一下就可以了。

点击Import -> CSV...选择对应的文件进行导入。

这样就可以看到从Excel中修改后的内容导入到Localization Table中啦。

乱码问题:https://blog.csdn.net/shishuijun/article/details/129961436
六、Build
如果需要打包项目的话还需要对Localization Tables进行Build一次,方法也很简单,下面看一下怎样操作。
打开菜单栏 Window -> Asset Management -> Addressables -> Groups。

然后在该窗口中选择Build -> New Build -> Defaul Build Script 进行Build,等待Build完成即可。

总结
Localization工具的优点在于该插件是Unity引擎原生解决方案,使用时只需要通过Package Manger导入即可。- 导入及配置都比较简单,对于一些文本量不是很大的项目来说,该方案非常的合适。
- 当项目对文本量需求非常大的时候,就需要配合Excel来管理了。
- 整理来说效果不错,操作简单易上手,基本功能都有,是值得学习的一款多语言本地化解决方案。
🎁🎁🎁 最后给大家推荐一个功能齐全而且很好用的 IP代理网站:IPIDEA
使用这个代理IP,可以很轻松地访问被封锁的网站,避免被追踪和监控,保护自己的隐私和安全。而且这个代理IP还可以帮助我们加速网页的加载速度,提高工作效率。
现在使用这个链接(https://share.ipidea.net/YYYYYY)注册的新用户还可以直接白嫖最少300M的流量,注册认证后最高可以送7.5G流量哦!
加上最近年终也有活动,优惠力度还是蛮大的,有需要的小伙伴可以去搞一下试试,注册 == 白嫖。
如果对此非常感兴趣之前没有用过或者不会使用的小伙伴也不用着急,在官网都有详细的教程可以看,后面有时间的话也可以出一期教程帮助大家快速上手使用的哦!
🎬 博客主页:https://xiaoy.blog.csdn.net
🎥 本文由 呆呆敲代码的小Y 原创 🙉
🎄 学习专栏推荐:Unity系统学习专栏
🌲 游戏制作专栏推荐:游戏制作
🌲Unity实战100例专栏推荐:Unity 实战100例 教程
🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📆 未来很长,值得我们全力奔赴更美好的生活✨
------------------❤️分割线❤️-------------------------




相关文章:
【Unity 实用工具篇】| 游戏多语言解决方案,官方插件Localization 实现本地化及多种语言切换
前言 【Unity 实用工具篇】| 游戏多语言解决方案,官方插件Localization 实现本地化及多种语言切换一、多语言本地化插件 Localization1.1 介绍1.2 效果展示1.3 使用说明 二、 插件导入并配置2.1 安装 Localization2.2 全局配置 三、多语言映射表3.1 创建多语言文本配…...
疯狂SQL转换系列- SQL for Tencent Cloud VectorDB
为了尽量保证使用者通过统一的SQL标准访问各类型数据库,我们这里开启了“疯狂SQL转换系列”。转换的语法效果不一定是最好的,更多是为用户提供一个统一的数据库交互体验。转换数据库目标的确认更多是内生的。基于我们对业务发展的需要。该向量库SQL转换的…...
Excel中的INDIRECT函数用法
当在 Excel 中使用 INDIRECT 函数时,它可以帮助我们通过引用字符串中的单元格地址来获取对应单元格的值。这个函数非常有用,特别是在需要动态地引用其他单元格的情况下。下面是 INDIRECT 函数的一些用法和示例: 基本用法: INDIREC…...
Spring-temp
IOC/DI实现步骤 1.配置元数据 2.实例化IOC 3.获取Bean 基于XML配置方式 管理组件 1.基于构造函数:有参、无参 2.基于静态工厂方法:有参、无参 依赖注入 1.构造函数 2.setter方法 Bean组件高级特性 1.作用域 2.生命周期 FactoryBean 基于注解 IOC Bean作…...
【C++干货铺】会搜索的二叉树(BSTree)
个人主页点击直达:小白不是程序媛 C系列专栏:C干货铺 代码仓库:Gitee 目录 前言: 二叉搜索树 二叉搜索树概念 二叉搜索树操作 二叉搜索树的查找 二叉搜索树的插入 二叉搜索树元素的删除 二叉搜索树的实现 BSTree结点 …...
【Spring AOP】 动态代理
一.AOP常见的实现方式 1.Spring AOP 2.aspectJ 注意:spring使用的是aspectJ的注解,但实现是spring自身实现的. 二.AOP原理 Spirng AOP原理 , 基于动态代理实现的. 三.代理模式 作用就是提供一个代理类,让我们在调用目标方法的时候,不再是直接对目标方法进行调用,而是通过代理类…...
NAT——网络地址转换
目录 一、概念 二、NAT的分类 1.静态NAT 1.1 静态NAT的配置 1.2 利用eNSP小实验加强对静态NAT的理解 2、动态NAT 三、NAPT——端口映射 四、Easy IP 使用一个公网地址可以让所有人都上公网 一、概念 随着Internet的发展和网络应用的增多,IPv4地址枯竭已经成为…...
Lambda 表达式的常见用法
文章目录 Lambda 表达式的常见用法使用Lambda表达式集合遍历使用Lambda表达式排序使用Lambda表达式过滤使用Lambda表达式映射使用Lambda表达式归约使用Lambda表达式分组使用Lambda表达式函数式接口的实现使用Lambda表达式线程的创建使用Lambda表达式进行Optional 操作使用Lambd…...
成本管理常用的ChatGPT通用提示词模板
成本分析:如何进行成本分析? 成本核算:如何进行成本核算? 成本控制:如何控制成本? 成本效益分析:如何进行成本效益分析? 成本预测:如何预测成本? 成本决…...
如何在PHP中处理日期和时间?
在 PHP 中,你可以使用内置的 DateTime 类和相关函数来处理日期和时间。以下是一些常见的日期和时间操作的示例: 使用 DateTime 类: 获取当前日期和时间: $currentDateTime new DateTime(); echo $currentDateTime->format(Y-…...
NO-IOT翻频,什么是翻频,电信为什么翻频
1.1 翻频迁移最终的目的就是减少网络的相互干扰,提供使用质量. 1.2 随着与日俱增的网络规模的扩大,网内干扰已成了影响网络的质量标准之一,为了保障电信上网体验,满足用户日益增长的网速需求,更好的服务客户,电信针对…...
云原生之深入解析OOM和CPU节流
一、前言 使用 Kubernetes 时,内存不足 (OOM) 错误和 CPU 节流是云应用程序中资源处理的主要难题,这是为什么呢?云应用程序中的 CPU 和内存要求变得越来越重要,因为它们与云成本直接相关。通过 limits 和 requests ,可…...
数据结构与算法之递归: LeetCode 93. 复原 IP 地址 (Typescript版)
复原 IP 地址 https://leetcode.cn/problems/restore-ip-addresses/ 描述 有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。 例如:“0.1.2.201” 和 “192.…...
json模块与jsonpath详解
数据提取之JSON与JsonPATH JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,它使得人们很容易的进行阅读和编写。同时也方便了机器进行解析和生成。适用于进行数据交互的场景,比如网站前台与后台之间的数据交互。 JSON和XML的比较可谓不…...
ubuntu20.04在noetic下编译orbslam2
ubuntu20.04在noetic下编译orbslam2 参考链接1:https://blog.csdn.net/qq_58869016/article/details/128660588 参考链接2:https://blog.csdn.net/dong123456789e/article/details/129693837 在noetic下的安装环境 1.库安装 sudo apt-get update sudo …...
64. 最小路径和
最小路径和 描述 : 给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。 说明:每次只能向下或者向右移动一步。 题目 : LeetCode 64.最小路径和 64. 最小路径和 解析 : class So…...
惰性加载函数(js的问题)
在web开发中,因为浏览器之间的实现差异,一些嗅探工作总是不可避免。 var addEvent function( elem, type, handler ){if ( window.addEventListener ){return elem.addEventListener( type, handler, false );}if ( window.attachEvent ){return elem.…...
jmeter,读取CSV文件数据的循环控制
1、构造csv数据 保存文件时需要注意文件的编码格式 id,name,limit,status,address,start_time 100,小米100,1000,1,某某会展中心101,2023/8/20 14:20 101,小米101,1001,1,某某会展中心102,2023/8/21 14:20 2、在线程组下添加【CSV数据文件设置】元件 3、CSV文件数据的循环控…...
移植LVGL到像素屏,从此玩转像素屏0门槛
硬件方面 先上渲染图 实物图 配置 主控:esp32 micro32 plus主频:240MhzFlash:8MPSRAM:2M 软件方面 众所周知,LVGL是一个十分优秀的图形框架,小到几百kb的单片机,大到Linux都可以运行。既然它…...
stateflow 之图函数、simulink函数和matlab函数使用及案例分析
目录 前言 1. 图函数graph function 2.simulink function 3.matlab function 4.调用stateflow中的几种函数方式 前言 对于stateflow实际上可以做simulink和matlab的所有任务,可以有matlab的m语言,也可以有simulink的模块,关于几种函数在…...
盘古信息PCB行业解决方案:以全域场景重构,激活智造新未来
一、破局:PCB行业的时代之问 在数字经济蓬勃发展的浪潮中,PCB(印制电路板)作为 “电子产品之母”,其重要性愈发凸显。随着 5G、人工智能等新兴技术的加速渗透,PCB行业面临着前所未有的挑战与机遇。产品迭代…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
AD学习(3)
1 PCB封装元素组成及简单的PCB封装创建 封装的组成部分: (1)PCB焊盘:表层的铜 ,top层的铜 (2)管脚序号:用来关联原理图中的管脚的序号,原理图的序号需要和PCB封装一一…...
