作者zxcmoney (修司)
看板GameDesign
标题[程式] Godot 国际化
时间Sun Jan 22 22:11:48 2023
GODOT本身其实就有对国际化(本地化 Localization)的设计
主要就是.PO档
在AssetLib中也能找到辅助工具,
我这次采用的 Translation editor 只能辅助编辑.PO就是了,
但无法应用在RichTextLabel上,替换对白,
所以这部分就只能自己写。
总之,目前的成果如下,
如果版友在未来有类似的需求可以拿去修改。
写入对话
func WriteDialog():
CG_Name = "999"
DLocale = "zh_TW"
talkArr = ["..."]
var Wfile = File.new()
Wfile.open("res://Dialog/"+str(DLocale)+"/d"+CG_Name+".ini",Wfile.WRITE)
Wfile.store_csv_line(talkArr)
Wfile.close()
DLocale = "zh_CN"
talkArr = ["..."]
Wfile = File.new()
Wfile.open("res://Dialog/"+str(DLocale)+"/d"+CG_Name+".ini",Wfile.WRITE)
Wfile.store_csv_line(talkArr)
Wfile.close()
DLocale = "en"
talkArr = ["..."]
Wfile = File.new()
Wfile.open("res://Dialog/"+str(DLocale)+"/d"+CG_Name+".ini",Wfile.WRITE)
Wfile.store_csv_line(talkArr)
Wfile.close()
DLocale = "ja"
talkArr = ["..."]
Wfile = File.new()
Wfile.open("res://Dialog/"+str(DLocale)+"/d"+CG_Name+".ini",Wfile.WRITE)
Wfile.store_csv_line(talkArr)
Wfile.close()
-----
解说
由於是一张CG对应一段对话
所以CG_Name跟对话文本的名称是一致的
DLocale = 是对应的地区
zh_TW是台湾地区
zh_CN是中国地区
en是英语地区
ja是日文地区
talkArr是对话内容,由於会以store_csv_line方式写入
所以是以","来分隔
以["我依约来了,不过先说好,要是太奇怪的要求我还是会拒绝的。"]为例
会先输出"我依约来了"
下一段话才是"不过先说好,要是太奇怪的要求我还是会拒绝的。"
之後就是开档案 写入 关闭的动作
----
读取对话
func readDialog(DialogName):
DLocale = TranslationServer.get_locale()
var Rfile = File.new()
Diglog_path = "res://Dialog/"+str(DLocale)+"/d"+str(DialogName)+".ini"
Rfile.open(Diglog_path,Rfile.READ)
talkArr = Rfile.get_csv_line()
Rfile.close()
txtArr = talkArr
-----
解说
TranslationServer.get_locale()为取得当前的地区
当前的地区可以配合 TranslationServer.set_locale("zh_TW") 设定
像是
func _on_OptionButton_item_selected(index):
match index:
0:
TranslationServer.set_locale("zh_TW")
1:
TranslationServer.set_locale("zh_CN")
2:
TranslationServer.set_locale("en")
3:
TranslationServer.set_locale("ja")
之後就是照对应的地区开档案载入txtArr阵列
-----
开始播放对话
func startDialog():
if GsRecord.Dialog_open:
$DialogBox.show()
$DBColorRect.show()
var talkTime = talkSpeed * txtArr[nowTalkIndex].length()
$DialogBox.text = txtArr[nowTalkIndex]
$DialogBox.percent_visible = 0
$Tween.interpolate_property($DialogBox,
"percent_visible",0,1,talkTime,Tween.TRANS_LINEAR,Tween.EASE_IN_OUT)
$Tween.start()
talkEnd = false
func _input(_event):
if Input.is_action_just_pressed("ui_accept")
and $DialogBox.visible == true:
if talkEnd == true :
nowTalkIndex += 1
if nowTalkIndex == txtArr.size():
$DialogBox.hide()
$DBColorRect.hide()
nowTalkIndex = 0
else:
startDialog()
else:
$DialogBox.percent_visible = 1
$Tween.stop($DialogBox)
talkEnd = true
func _on_Tween_tween_completed(_object, _key):
talkEnd = true
-----
解说
这其实分成三段程式
第一段的startDialog主要工作是读取阵列内容
写入对话栏後一个字一个字播放。
GsRecord.Dialog_open 这是判断是否要有开启对白的开关
$DialogBox.show()则是开启对话栏
$DBColorRect.show()则是对话栏的背景色
talkTime是设定对话时间,依照对话速度*字数设定
$DialogBox.text是将阵列内容写入对话栏
$DialogBox.percent_visible = 0 即使设定成显示0%的部分
$Tween.interpolate_property则是配合Tween节点
从0到1播放对话栏的内容,简单说就是一次一个字播放。
$Tween.start()就是开始播放
talkEnd = false 表示现在是对话还没讲完
而第二段
func _input(_event):
if Input.is_action_just_pressed("ui_accept") and $DialogBox.visible == true:
就是对输入映射做侦测
这部分可以在GODOT的 专案>专案设定>输入映射 做设定
如果对话栏开着,就会判断目前对话是否结束
如果这段对话结束且没有内容就关闭对话栏,
还有内容就载入对话继续讲,
如果对话还没结束,就显示全部内容後,将对话状态设为讲完了。
第三段
func _on_Tween_tween_completed(_object, _key):
talkEnd = true
则是Tween传来的讯息,当播放完毕时会传来,
就将对话状态设为讲完了
-----
当然这就某方面来说蛮阳春的
一方面也是这作品不复杂就是了
没有做CG抽换 或 对话脚色的头像抽换
不过这也是该专案相对有通用性的部分了
总之
有需要就拿去用吧
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.170.146.92 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/GameDesign/M.1674396710.A.2F0.html
1F:推 Bencrie: .po 是 GNU gettext 那套? 01/24 15:49
应该是类似
照说明文件的说法是比GNU gettext有更多限制
https://reurl.cc/KX7oDR
※ 编辑: zxcmoney (114.42.97.77 台湾), 01/26/2023 10:30:06
2F:推 chchwy: 推实际心得 01/28 13:45