微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Unity游戏项目中后期如何做海外版翻译

一. 多语言和翻译的区别

1. 多语言

游戏中可以动态切换语言,比如中文、英文、西班牙文,这要求项目中要并存多语言的配置,比如i18n_zh.json、i18n_en.json、i18n_es.json,游戏根据语言设置动态加载对应的i18文件

2. 翻译

把游戏中的中文翻译成外文,覆盖原来的中文文字,项目中只存一份i18.json

3. 优劣

方案 优点 缺点
多语言 灵活,方便横向扩展 1 逻辑上更复杂,需要在项目早期的时候就做好框架,如果后期改多语言,修改量比较大;2 如果有使用美术表现的文字,也需要支持动态切换图集,包内需要保护多种语言的美术字体
翻译 代码改动少,资源简单 不够灵活,不易横向扩展

二. 项目中后期如何做翻译修改

1. i18的翻译

一般项目中需要有一个i18配置,配置项目中程序用到的中文文字,结构类似如下

{
	"1": "登录成功",
	"2": "账号或密码错误",
	"3": "注册"
}

翻译的话,直接把上面的i18翻译成对应的语言文字即可,如

{
	"1": "Login successful",
	"2": "Wrong account or password",
	"3": "Regist"
}

2. excel配置表的翻译

除了i18,其他配置表中还有很多中文配置,比如背包配置表,道具名、描述等等字段都是中文的,大量的excel配置,这个时候,可以用python来批量分析这些excel配置表,把中文过滤出来
把下面的phthon脚本放在excel配置文件目录的根目录,然后执行
运行环境python2

# coding=utf-8
import xlrd
import re
import os
import io

txt_t=[]
txt = ""

def filter_zh_from_excel(f):
    xl = xlrd.open_workbook(f)
    sheets = xl.sheets()
    for sheet in sheets:
        nrows = sheet.nrows
        for i in range(nrows):
            #表头2行不检测
            if i >= 2:
                row_data = sheet.row(i)
                j = 0
                for data in row_data:
                    j = j + 1
                    if 1 == data.ctype:
                        zhmodel = re.compile(u'[\u4e00-\u9fa5]')
                        if zhmodel.search(data.value):                
                            #print('t: %s,s: %s,r: %d,c: %d,v: %s' %(f,sheet.name,i+1,j,data.value))
                            txt = '%s|%s|%d|%d|%s' %(f, sheet.name.encode('gbk'), i+1,j, data.value.encode('gbk'))
                            txt_t.append(txt.decode('gbk').encode('utf-8'))

             
def get_all_excels():
    for root, dirs, fs in os.walk('.'): 
        for f in fs:
            if f.endswith('.xlsx') or f.endswith('.xls'):
                print(os.path.join(root,  f))
                filter_zh_from_excel(os.path.join(root,  f))
                        

def write_output():
    f = open('output.csv', 'w')
    f.write('文件|sheet|行|列|内容\n ')
    for txt in txt_t:
        f.write(txt+'\n')
    f.close()


get_all_excels()
write_output()
print('done')

运行后会输出如下的表格

在这里插入图片描述


接下来,就可以把这个中文列表给外包进行翻译
当外包翻译好之后,可以得到如下的表格

在这里插入图片描述


加载到内存

Dictionary<string, string> languageMap;

修改UILabel的text的set属性

public string text
{
	set
	{	
		if(languageMap.Contains(value))
		{
			mText = languageMap[value];
		}
	}
}

3. 预设中的中文翻译

还有预设里也有中文,写个工具扫码一下

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Text;
using UnityEditor;
using System.Text.RegularExpressions;
using System;


public class PrefabLblTextZnFilter
{
    [MenuItem("Tools/扫描预设Label中文")]
    public static void StartPrefabLblTextZnFilter()
    {
        var fs = Directory.GetFiles(Application.dataPath + "\\GameRes\\", "*.prefab", SearchOption.AllDirectories);
        List<string> outputs = new List<string>();
        RunProgress(fs, "扫描预设Label中文", (f) =>
        {
            var assetPath = f.Replace(Application.dataPath, "Assets");
            var obj = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
            var lbls = obj.GetComponentsInChildren<UILabel>();
            foreach (var lbl in lbls)
            {
                if (IfContainChinse(lbl.text))
                {
                    Debug.Log(lbl.text);
                    outputs.Add(assetPath + "|" + lbl.gameObject + "|" + lbl.text);
                }
            }
        }, () =>
         {
             var outputPath = Application.dataPath + "\\..\\prefabl_lbl_zn.csv";
             using (StreamWriter sw = new StreamWriter(outputPath))
             {
                 foreach (var lin in outputs)
                 {
                     sw.WriteLine(lin);
                 }
             }
             Debug.Log("svae output done: " + outputPath);
         });
    }
    
    
    private static void RunProgress(string[] fs, string title, Action<string> itemCb, Action finishCb = null)
    {
        RunProgress<string>(fs, title, itemCb, finishCb);
    }

    private static void RunProgress<T>(T[] fs, Action<T> itemCb, Action finishCb = null)
    {
        int startIndex = 0;
        Debug.Log(title + " start <<<<<");
        EditorApplication.update = delegate ()
        {
            var f = fs[startIndex];
            bool isCancel = EditorUtility.displayCancelableProgressBar(title, f.ToString(), (float)startIndex / fs.Length);
            try
            {
                if (null != itemCb) itemCb((T)f);
            }
            catch (Exception ex)
            {
                Debug.LogError(ex);
                isCancel = true;
            }

            startIndex++;
            if (isCancel || startIndex >= fs.Length)
            {
                EditorUtility.ClearProgressBar();
                EditorApplication.update = null;
                startIndex = 0;
                Debug.Log(title + " done >>>>>");
                if (null != finishCb)
                    finishCb();
            }
        };
    }

    private static bool IfContainChinse(string str)
    {
        return Regex.IsMatch(str, @"[\u4e00-\u9fa5]");
    }
}

点击菜单 Tools/扫描预设Label中文输出如下的表格

在这里插入图片描述


同上给外包翻译后得到一个语言配置表,加载到内存

Dictionary<string, string> languageMap;

实例化界面预设的时候,修改UILabel的text为翻译语言

var lbls = GetComponentsInChildren<UILabel>(panelObj);
for(int i = 0, len = lbls.Lenght; i < len; ++i)
{
	var text = lbls[i].text;
	// 如果语言容器中存在
	if(languageMap.Contains(text))
	{
		lbls[i].text = languageMap[text];
	}
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐