[Godot] C#读取CSV表格创建双层字典实现本地化

最近研究了一下本地化,给大家用简单易懂的方式说明我是怎么实现的,使用CSV表格填写翻译,然后在Godot中读取为字典

表格填写

首先,我们表格可以按照下面这种格式填写

id zh en ja ru es de fr
apple 苹果 apple リンゴ яблоко manzana Apfel pomme
banana 香蕉 banana バナナ банан plátano Banane banane
orange 橙子 orange オレンジ апельсин naranja Orange orange

大家看表格应该能明白,用第一列作为键,然后再用语言作为第二层的键,就能调用到对应语言的文本了,有一点需要注意,我们保存的时候,格式需要选择为 CSV UTF-8(用逗号分隔)的格式

打开查看,我们可以看到是下面这种格式

[Godot] C#读取CSV表格创建双层字典实现本地化_第1张图片

有一点需要注意,当我们打开表格的时候是有保护的,这时候不能在这里面修改保存,关闭表格即可

导入表格

我们直接把表格拖入到Godot里面,你可能会注意到Godot报错

Failed to open 'C:\Users\Administrator\Videos\Fruits.csv'.

我们在资源管理器进行移动,Godot中会自动创建一堆.translation格式的翻译文件

[Godot] C#读取CSV表格创建双层字典实现本地化_第2张图片

我们需要在导入中设置为原样导出,选择后点击重新导入即可

[Godot] C#读取CSV表格创建双层字典实现本地化_第3张图片

接下来,你会发现文件变成了X号的图标,不要双击打开他,Godot会直接闪退,我们删除这些创建出来的.translation文件就行

[Godot] C#读取CSV表格创建双层字典实现本地化_第4张图片

读取代码

首先,我们需要创建一个双层字典用来保存翻译文本

using Godot.Collections;        //注意,使用字典就需要写这个

[Export]    //暴露在编辑器中
public Dictionary> language = new Dictionary>();

private string csv_language_path = "res://Language/Fruits.csv";    //文件路径
public string Now_Language = "zh";    //当前语言

然后我们写一个函数,在初始化的时候把数据写入字典

void Load_CSV_Language()
    {
        if (!FileAccess.FileExists(csv_language_path))  //判断文件是否存在
        {
            GD.Print($"{csv_language_path}文件不存在");
            return;
        }

        var file = FileAccess.Open(csv_language_path, FileAccess.ModeFlags.Read);

        var header = file.GetLine().Split(",");    //获取语言头

        while (!file.EofReached())      //循环,直到指向尾部
        {
            Dictionary lang = new Dictionary();     //创建内层字典
            var line = file.GetLine().Split(",");   //获取行(键,语言,语言,语言)

            if (string.IsNullOrWhiteSpace(line[0])) continue;       //跳过空行,防止越界

            for (int i = 1; i < line.Length; i++)
            {
                lang.Add(header[i], line[i]);
            }
            language.Add(line[0], lang);
        }

        file.Close();       //关闭文件流
    }

接下来,我们写一个获取对应文本的函数方法即可

public string Get_Language(string key)      //返回本地化语言
    {
        return language[key][Now_Language];
    }

单例加载

有一点,在C#中使用Godot的自动加载功能,我们需要额外写一些代码

[Godot] C#读取CSV表格创建双层字典实现本地化_第5张图片

我这里则是放在了树的加载函数中,大家根据需要进行调整

public static LanguageManager Instance;

public override void _EnterTree()
    {
        Instance = this;
        Load_CSV_Language();    //调用加载字典函数
    }

    public override void _ExitTree()
    {
        Instance = null;
    }

这样,我们运行场景,就能看到场景的根节点下,多了一个节点

[Godot] C#读取CSV表格创建双层字典实现本地化_第6张图片

接下来,我们只需要在其他节点中获取即可调用 Get_Language 方法了

public LanguageManager languageManager;

public override void _Ready()
    {
        languageManager = GetTree().Root.GetNode("LanguageManager");
    }

切换语言

为了在切换语言的时候更改场景的文本,我们先把所有的设置文本的函数都放在一个函数中,大家可以参照我的示例进行修改

public void SetLanguage()
    {
        Get_Language();
        SetText();
    }

public void Get_Language()      //获取翻译
    {
        name = languageManager.Get_Language($"{id}");
    }

private void SetText()      //设置文本
    {
        T_name.Text = name;
    }

我们修改本地化脚本的 Now_Language 变量

private string _Now_Language = "zh";
    public string Now_Language
    {
        get => _Now_Language;
        set
        {
            _Now_Language = value;
            UpdateLanguage();    //修改值时调用
        }

    }

我们可以给脚本的节点加上分组,使用CallGroup方法调用函数

public void UpdateLanguage()    //切换语言
    {
        GetTree().CallGroup("Text", "SetLanguage");     //通知组,调用设置语言方法
    }

这里我创建的组叫“Text”,我们需要在Godot中把组分给节点(或者在脚本中使用AddToGroup方法也可以)

[Godot] C#读取CSV表格创建双层字典实现本地化_第7张图片

这样,我们修改 Now_Language 变量,文本就会发生改变

结语

通过这种结构化的双层字典方案,我们成功构建了一个动态可扩展的本地化系统。如果项目文本量巨大,我们可以进行异步加载来进行优化,大家可以根据自己的需要进行修改。

你可能感兴趣的:(Godot,godot,游戏引擎,c#)