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

相关文章

golang中reflect包的常用方法

《golang中reflect包的常用方法》Go反射reflect包提供类型和值方法,用于获取类型信息、访问字段、调用方法等,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值... 目录reflect包方法总结类型 (Type) 方法值 (Value) 方法reflect包方法总结

C# 比较两个list 之间元素差异的常用方法

《C#比较两个list之间元素差异的常用方法》:本文主要介绍C#比较两个list之间元素差异,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. 使用Except方法2. 使用Except的逆操作3. 使用LINQ的Join,GroupJoin

Go语言中nil判断的注意事项(最新推荐)

《Go语言中nil判断的注意事项(最新推荐)》本文给大家介绍Go语言中nil判断的注意事项,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1.接口变量的特殊行为2.nil的合法类型3.nil值的实用行为4.自定义类型与nil5.反射判断nil6.函数返回的

python常用的正则表达式及作用

《python常用的正则表达式及作用》正则表达式是处理字符串的强大工具,Python通过re模块提供正则表达式支持,本文给大家介绍python常用的正则表达式及作用详解,感兴趣的朋友跟随小编一起看看吧... 目录python常用正则表达式及作用基本匹配模式常用正则表达式示例常用量词边界匹配分组和捕获常用re

Go语言数据库编程GORM 的基本使用详解

《Go语言数据库编程GORM的基本使用详解》GORM是Go语言流行的ORM框架,封装database/sql,支持自动迁移、关联、事务等,提供CRUD、条件查询、钩子函数、日志等功能,简化数据库操作... 目录一、安装与初始化1. 安装 GORM 及数据库驱动2. 建立数据库连接二、定义模型结构体三、自动迁

Go语言代码格式化的技巧分享

《Go语言代码格式化的技巧分享》在Go语言的开发过程中,代码格式化是一个看似细微却至关重要的环节,良好的代码格式化不仅能提升代码的可读性,还能促进团队协作,减少因代码风格差异引发的问题,Go在代码格式... 目录一、Go 语言代码格式化的重要性二、Go 语言代码格式化工具:gofmt 与 go fmt(一)

gitlab安装及邮箱配置和常用使用方式

《gitlab安装及邮箱配置和常用使用方式》:本文主要介绍gitlab安装及邮箱配置和常用使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1.安装GitLab2.配置GitLab邮件服务3.GitLab的账号注册邮箱验证及其分组4.gitlab分支和标签的

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

Go学习记录之runtime包深入解析

《Go学习记录之runtime包深入解析》Go语言runtime包管理运行时环境,涵盖goroutine调度、内存分配、垃圾回收、类型信息等核心功能,:本文主要介绍Go学习记录之runtime包的... 目录前言:一、runtime包内容学习1、作用:① Goroutine和并发控制:② 垃圾回收:③ 栈和