Godot 学习笔记(5):国际化多语言翻译,包含常用10种语言机翻!

2024-03-27 06:52

本文主要是介绍Godot 学习笔记(5):国际化多语言翻译,包含常用10种语言机翻!,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • 国际化
    • 翻译Api选择
      • 小牛测试
    • 语言选择
    • 代码逻辑
      • 实体对象
      • 翻译帮助类
        • 导出模板
        • 读取文件
        • 翻译
          • 测试
          • 多语言测试
        • 综合翻译
          • 文件准备
          • 测试代码
          • 测试结果
    • 完整代码
      • 实体类
      • 翻译帮助类
      • 网络帮助类
    • 最终效果
      • 翻译前
      • 翻译中
      • 翻译后
  • 总结

前言

为了面向更大的市场,国际化是肯定的。我想如果我开发游戏,至少要支持两种语言,英语和中文简体。

国际化

翻译Api选择

在这里插入图片描述
国内Api也有三种选择,百度,有道和小牛。我这里就选小牛了,比较便宜。

小牛测试

小牛翻译平台

使用PostMan测试成功
在这里插入图片描述

语言选择

在这里插入图片描述
在这里插入图片描述

首先,作为中文为母语,所以我至少支持三种语言。简中,繁中和英语。下面附上小牛的对应参数表

语言参数
简中zh
繁中cht
英语en
德语de
法语fr
西班牙语es
意大利语it
葡萄牙语pt
俄语ru
日语ja
韩语ko

吐槽一下,写了这么多,我都快认不清这个【语】字是什么意思了。

原文选择我这里选择英语作为原文,因为这样可以顺便学一下英语。

代码逻辑

这里使用了MiniExcel
在这里插入图片描述
Json化方式
在这里插入图片描述

实体对象

public class TranslateModel
{public TranslateModel() { }public TranslateModel(string scene,string key,string en) {Scene = scene;Key = key;EN = en;}public string Scene { get; set; }public string Key { get; set; }/// <summary>/// 英语/// </summary>public string EN { get; set; }/// <summary>/// 简体中文/// </summary>public string ZH { get; set; }/// <summary>/// 繁体中文/// </summary>public string CHT { get; set; }/// <summary>/// 德语/// </summary>public string DE { get; set; }/// <summary>/// 法语/// </summary>public string FR { get; set; }/// <summary>/// 西班牙语/// </summary>public string ES { get; set; }/// <summary>/// 意大利语/// </summary>public string IT { get; set; }/// <summary>/// 葡萄牙语/// </summary>public string PT { get; set; }/// <summary>/// 俄语/// </summary>public string RU { get; set; }/// <summary>/// 日语/// </summary>public string JA { get; set; }/// <summary>/// 韩语/// </summary>public string KO { get; set; }
}

翻译帮助类

public class TranslateHelper
{/// <summary>
/// 存放读取的数据
/// </summary>
public IEnumerable<TranslateModel> Translates { get; private set; }/// <summary>/// 模板路径/// </summary>public readonly string TemplateUrl = "Assests/translate_template.xlsx";/// <summary>/// 读取路径/// </summary>public readonly string ReadUrl = "Assests/translate_read.xlsx";/// <summary>/// 翻译导出路径/// </summary>public readonly string WriteUrl = "Assests/translate_read.xlsx";public TranslateHelper(){}}
导出模板
/// <summary>
/// 导出模板,如果文件存在则跳过
/// </summary>
public void CreateTemplate()
{if (!File.Exists(TemplateUrl)){var config = new OpenXmlConfiguration(){TableStyles = TableStyles.None};var saveTemplate = new List<TranslateModel>();saveTemplate.Add(new TranslateModel("Main", "Hello", "Hello World!"));MiniExcel.SaveAs(TemplateUrl, saveTemplate,configuration: config);}
}

在这里插入图片描述

读取文件

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

翻译

这里用一下我的封装

C# HttpClient Get Post简单封装

先来一个Hello world!翻译

在这里插入图片描述

public class TranslateHelper
{public enum Language { zh, cht, en, de, fr, es, it, pt, ru, ja, ko }/// <summary>/// 存放读取的数据/// </summary>public IEnumerable<TranslateModel> Translates { get; private set; }/// <summary>/// 模板路径/// </summary>public const string TemplateUrl = "Assests/translate_template.xlsx";/// <summary>/// 读取路径/// </summary>public const string ReadUrl = "Assests/translate_read.xlsx";/// <summary>/// 翻译导出路径/// </summary>public const string WriteUrl = "Assests/translate_read.xlsx";public const string API_KEY = "你的key";public const string APPID = "你的ip";public const string API_URL = "https://api.niutrans.com/NiuTransServer/translation";public TranslateHelper(){}/// <summary>/// 导出模板,如果文件存在则跳过/// </summary>public void CreateTemplate(){if (!File.Exists(TemplateUrl)){var config = new OpenXmlConfiguration(){TableStyles = TableStyles.None};var saveTemplate = new List<TranslateModel>();saveTemplate.Add(new TranslateModel("Main", "Hello", "Hello World!"));MiniExcel.SaveAs(TemplateUrl, saveTemplate, configuration: config);}}public void Read(){Translates = MiniExcel.Query<TranslateModel>(ReadUrl);}public async Task<string> TranslateFromEN(string en, Language language){//这个是我自己封装的,你也可以用微软官方的原生httpclientvar httpHelper = new MyHttpHelper(API_URL);var data = new{src_text = en,from = "en",to = language.ToString(),apikey = API_KEY,};var res = await httpHelper.JsonHttpPost<Dictionary<string,string>>("", data, null);var str = res["tgt_text"];return str;}}
测试
        static void Main(string[] args){var helper = new TranslateHelper();helper.CreateTemplate();Console.WriteLine("开始!");Task.Run(async () =>{var res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.zh);Console.WriteLine(res);});Console.WriteLine("结束!");Console.ReadKey();}

在这里插入图片描述

多语言测试
Task.Run(async () =>
{var res = "";res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.zh);Console.WriteLine(res);res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.cht);Console.WriteLine(res);res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.de);Console.WriteLine(res);res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.fr);Console.WriteLine(res);res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.es);Console.WriteLine(res);res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.it);Console.WriteLine(res);res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.pt);Console.WriteLine(res);res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.ru);Console.WriteLine(res);res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.ja);Console.WriteLine(res);res = await helper.TranslateFromEN("Hello world!", TranslateHelper.Language.ko);Console.WriteLine(res);
});

在这里插入图片描述

综合翻译
/// <summary>
/// 读取并写入机翻结果
/// </summary>
/// <returns></returns>
public async Task ReadAndWrite()
{if(!File.Exists(ReadUrl)){Console.WriteLine($"[{ReadUrl}]文件不存在,读取失败");return;}else{Translates = MiniExcel.Query<TranslateModel>(ReadUrl).ToArray();}if (File.Exists(WriteUrl)){Console.WriteLine($"[{WriteUrl}]文件已存在,跳过翻译");return ;}else{for(var i = 0;i< Translates.Count();i++){Console.WriteLine($"翻译进度:[{i}/{Translates.Count()}]");Translates[i] = await TranslateAllFromEN(Translates[i]);}//将数据保留MiniExcel.SaveAs(WriteUrl, Translates);}}/// <summary>
/// 从EN翻译全部
/// </summary>
/// <returns></returns>
public async Task<TranslateModel> TranslateAllFromEN(TranslateModel translateModel)
{if (translateModel.EN != null && translateModel.EN != ""){var en = translateModel.EN;translateModel.ZH = await TranslateFromEN(en, Language.zh);translateModel.CHT = await TranslateFromEN(en, Language.cht);translateModel.DE = await TranslateFromEN(en, Language.de);translateModel.FR = await TranslateFromEN(en, Language.fr);translateModel.ES = await TranslateFromEN(en, Language.es);translateModel.IT = await TranslateFromEN(en, Language.it);translateModel.PT = await TranslateFromEN(en, Language.pt);translateModel.RU = await TranslateFromEN(en, Language.ru);translateModel.JA = await TranslateFromEN(en, Language.ja);translateModel.KO = await TranslateFromEN(en, Language.ko);Console.WriteLine(JsonConvert.SerializeObject(translateModel));}else{Console.WriteLine($"Scene[{translateModel.Scene}],Key[{translateModel.Key}]的EN为空");}return translateModel;}/// <summary>
/// EN单独翻译
/// </summary>
/// <param name="en"></param>
/// <param name="language"></param>
/// <returns></returns>
public async Task<string> TranslateFromEN(string en, Language language)
{//防止请求过快,小牛API并发有限制await Task.Delay(100);//Console.WriteLine(language.ToString());var httpHelper = new MyHttpHelper(API_URL);var data = new{src_text = en,from = "en",to = language.ToString(),apikey = API_KEY,};var res = await httpHelper.JsonHttpPost<Dictionary<string,string>>("", data, null);var str = res["tgt_text"];return str;
}
文件准备

在这里插入图片描述

在这里插入图片描述

测试代码
Task.Run(async () =>
{await helper.ReadAndWrite();});
测试结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完整代码

实体类

public class TranslateModel
{public TranslateModel() { }public TranslateModel(string scene,string key,string en) {Scene = scene;Key = key;EN = en;}public string Scene { get; set; }public string Key { get; set; }/// <summary>/// 英语/// </summary>public string EN { get; set; }/// <summary>/// 简体中文/// </summary>public string ZH { get; set; }/// <summary>/// 繁体中文/// </summary>public string CHT { get; set; }/// <summary>/// 德语/// </summary>public string DE { get; set; }/// <summary>/// 法语/// </summary>public string FR { get; set; }/// <summary>/// 西班牙语/// </summary>public string ES { get; set; }/// <summary>/// 意大利语/// </summary>public string IT { get; set; }/// <summary>/// 葡萄牙语/// </summary>public string PT { get; set; }/// <summary>/// 俄语/// </summary>public string RU { get; set; }/// <summary>/// 日语/// </summary>public string JA { get; set; }/// <summary>/// 韩语/// </summary>public string KO { get; set; }
}

翻译帮助类

public class TranslateHelper
{public enum Language { zh, cht, en, de, fr, es, it, pt, ru, ja, ko }/// <summary>/// 存放读取的数据/// </summary>public TranslateModel[] Translates { get; private set; }/// <summary>/// 模板路径/// </summary>public const string TemplateUrl = "Assests/translate_template.xlsx";/// <summary>/// 读取路径/// </summary>public const string ReadUrl = "Assests/translate_read.xlsx";/// <summary>/// 翻译导出路径/// </summary>public const string WriteUrl = "Assests/translate_write.xlsx";public const string API_KEY = "你的key";public const string APPID = "你的appid";public const string API_URL = "https://api.niutrans.com/NiuTransServer/translation";public TranslateHelper(){}/// <summary>/// 导出模板,如果文件存在则跳过/// </summary>public void CreateTemplate(){if (!File.Exists(TemplateUrl)){var config = new OpenXmlConfiguration(){TableStyles = TableStyles.None};var saveTemplate = new List<TranslateModel>();saveTemplate.Add(new TranslateModel("Main", "Hello", "Hello World!"));MiniExcel.SaveAs(TemplateUrl, saveTemplate, configuration: config);}else{Console.WriteLine($"[{TemplateUrl}]文件已存在,跳过创建");}}/// <summary>/// 读取并写入机翻结果/// </summary>/// <returns></returns>public async Task ReadAndWrite(){if(!File.Exists(ReadUrl)){Console.WriteLine($"[{ReadUrl}]文件不存在,读取失败");return;}else{Translates = MiniExcel.Query<TranslateModel>(ReadUrl).ToArray();}if (File.Exists(WriteUrl)){Console.WriteLine($"[{WriteUrl}]文件已存在,跳过翻译");return ;}else{for(var i = 0;i< Translates.Count();i++){Console.WriteLine($"翻译进度:[{i+1}/{Translates.Count()}]");Translates[i] = await TranslateAllFromEN(Translates[i]);}var config = new OpenXmlConfiguration(){TableStyles = TableStyles.None};//将数据保留MiniExcel.SaveAs(WriteUrl, Translates,configuration:config);}}/// <summary>/// 从EN翻译全部/// </summary>/// <returns></returns>public async Task<TranslateModel> TranslateAllFromEN(TranslateModel translateModel){if (translateModel.EN != null && translateModel.EN != ""){var en = translateModel.EN;translateModel.ZH = await TranslateFromEN(en, Language.zh);translateModel.CHT = await TranslateFromEN(en, Language.cht);translateModel.DE = await TranslateFromEN(en, Language.de);translateModel.FR = await TranslateFromEN(en, Language.fr);translateModel.ES = await TranslateFromEN(en, Language.es);translateModel.IT = await TranslateFromEN(en, Language.it);translateModel.PT = await TranslateFromEN(en, Language.pt);translateModel.RU = await TranslateFromEN(en, Language.ru);translateModel.JA = await TranslateFromEN(en, Language.ja);translateModel.KO = await TranslateFromEN(en, Language.ko);Console.WriteLine(JsonConvert.SerializeObject(translateModel));}else{Console.WriteLine($"Scene[{translateModel.Scene}],Key[{translateModel.Key}]的EN为空");}return translateModel;}/// <summary>/// EN单独翻译/// </summary>/// <param name="en"></param>/// <param name="language"></param>/// <returns></returns>public async Task<string> TranslateFromEN(string en, Language language){//防止请求过快,小牛API并发有限制await Task.Delay(100);//Console.WriteLine(language.ToString());var httpHelper = new MyHttpHelper(API_URL);var data = new{src_text = en,from = "en",to = language.ToString(),apikey = API_KEY,};var res = await httpHelper.JsonHttpPost<Dictionary<string,string>>("", data, null);var str = res["tgt_text"];return str;}}

网络帮助类

public class MyHttpHelper
{private string baseUrl;/// <summary>/// 基础Api/// </summary>public string BaseUrl{get{return baseUrl;}set{baseUrl = value;MyHttpClient = new HttpClient(){BaseAddress = new Uri(baseUrl)};}}public HttpClient MyHttpClient { get; set; }public MyHttpHelper(){}public MyHttpHelper(string baseUrl){BaseUrl = baseUrl;}/// <summary>/// 序列化返回值/// </summary>/// <typeparam name="T"></typeparam>/// <param name="api"></param>/// <param name="strParams"></param>/// <returns></returns>public async Task<T> JsonHttpGet<T>(string api, Dictionary<string, string> strParams){var res = await MyHttpGet(api, strParams);return await res.Content.ReadFromJsonAsync<T>();}/// <summary>/// 序列化返回值/// </summary>/// <typeparam name="T"></typeparam>/// <param name="api"></param>/// <param name="value"></param>/// <param name="strParams"></param>/// <returns></returns>public async Task<T> JsonHttpPost<T>(string api, object value, Dictionary<string, string> strParams){var res = await MyHttpPost(api, value, strParams);return await res.Content.ReadFromJsonAsync<T>();}/// <summary>/// 序列化请求/// </summary>/// <param name="api"></param>/// <param name="param"></param>/// <returns></returns>public async Task<HttpResponseMessage> MyHttpGet(string api, Dictionary<string, string> param){string paramStr = DictionaryToParams(param);return await MyHttpClient.GetAsync(api + paramStr);}/// <summary>/// 自定义的转发功能/// </summary>/// <param name="api"></param>/// <param name="dataname"></param>/// <param name="value"></param>/// <returns></returns>public Task<HttpResponseMessage> MyHttpPost(string api, object value, Dictionary<string, string> strParams){return MyHttpClient.PostAsync(api + DictionaryToParams(strParams), new StringContent(JsonConvert.SerializeObject(value), Encoding.UTF8, "application/json"));}/// <summary>/// 字典转参数/// </summary>/// <param name="param"></param>/// <returns></returns>public string DictionaryToParams(Dictionary<string, string> param){var res = "";if (param != null){var list = param.ToList();if (list.Count != 0){for (var i = 0; i < list.Count; i++){if (i != 0){res += "&";}res += $"{list[i].Key}={list[i].Value}";}res = "?" + res;}}return res;}
}

最终效果

翻译前

在这里插入图片描述

翻译中

在这里插入图片描述

翻译后

在这里插入图片描述

总结

多语言发布,这样可以让我们的游戏在更多的国家用户使用。虽然我暂时没有这个需求,但是说不定也有别的项目需要多语言的本地化接入。

这篇关于Godot 学习笔记(5):国际化多语言翻译,包含常用10种语言机翻!的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/851261

相关文章

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

从基础到高级详解Go语言中错误处理的实践指南

《从基础到高级详解Go语言中错误处理的实践指南》Go语言采用了一种独特而明确的错误处理哲学,与其他主流编程语言形成鲜明对比,本文将为大家详细介绍Go语言中错误处理详细方法,希望对大家有所帮助... 目录1 Go 错误处理哲学与核心机制1.1 错误接口设计1.2 错误与异常的区别2 错误创建与检查2.1 基础

Python打包成exe常用的四种方法小结

《Python打包成exe常用的四种方法小结》本文主要介绍了Python打包成exe常用的四种方法,包括PyInstaller、cx_Freeze、Py2exe、Nuitka,文中通过示例代码介绍的非... 目录一.PyInstaller11.安装:2. PyInstaller常用参数下面是pyinstal

Python 常用数据类型详解之字符串、列表、字典操作方法

《Python常用数据类型详解之字符串、列表、字典操作方法》在Python中,字符串、列表和字典是最常用的数据类型,它们在数据处理、程序设计和算法实现中扮演着重要角色,接下来通过本文给大家介绍这三种... 目录一、字符串(String)(一)创建字符串(二)字符串操作1. 字符串连接2. 字符串重复3. 字

Go语言中json操作的实现

《Go语言中json操作的实现》本文主要介绍了Go语言中的json操作的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录 一、jsOChina编程N 与 Go 类型对应关系️ 二、基本操作:编码与解码 三、结构体标签(Struc

python语言中的常用容器(集合)示例详解

《python语言中的常用容器(集合)示例详解》Python集合是一种无序且不重复的数据容器,它可以存储任意类型的对象,包括数字、字符串、元组等,下面:本文主要介绍python语言中常用容器(集合... 目录1.核心内置容器1. 列表2. 元组3. 集合4. 冻结集合5. 字典2.collections模块

基于Go语言开发一个 IP 归属地查询接口工具

《基于Go语言开发一个IP归属地查询接口工具》在日常开发中,IP地址归属地查询是一个常见需求,本文将带大家使用Go语言快速开发一个IP归属地查询接口服务,有需要的小伙伴可以了解下... 目录功能目标技术栈项目结构核心代码(main.go)使用方法扩展功能总结在日常开发中,IP 地址归属地查询是一个常见需求:

JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法

《JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法》:本文主要介绍JavaScript中比较两个数组是否有相同元素(交集)的三种常用方法,每种方法结合实例代码给大家介绍的非常... 目录引言:为什么"相等"判断如此重要?方法1:使用some()+includes()(适合小数组)方法2

SpringBoot 获取请求参数的常用注解及用法

《SpringBoot获取请求参数的常用注解及用法》SpringBoot通过@RequestParam、@PathVariable等注解支持从HTTP请求中获取参数,涵盖查询、路径、请求体、头、C... 目录SpringBoot 提供了多种注解来方便地从 HTTP 请求中获取参数以下是主要的注解及其用法:1

GO语言短变量声明的实现示例

《GO语言短变量声明的实现示例》在Go语言中,短变量声明是一种简洁的变量声明方式,使用:=运算符,可以自动推断变量类型,下面就来具体介绍一下如何使用,感兴趣的可以了解一下... 目录基本语法功能特点与var的区别适用场景注意事项基本语法variableName := value功能特点1、自动类型推