[程式] Godot 國際化

看板GameDesign (遊戲設計)作者 (修司)時間1年前 (2023/01/22 22:11), 1年前編輯推噓1(100)
留言1則, 1人參與, 1年前最新討論串1/1
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://www.ptt.cc/bbs/GameDesign/M.1674396710.A.2F0.html

01/24 15:49, 1年前 , 1F
.po 是 GNU gettext 那套?
01/24 15:49, 1F
應該是類似 照說明文件的說法是比GNU gettext有更多限制 https://reurl.cc/KX7oDR ※ 編輯: zxcmoney (114.42.97.77 臺灣), 01/26/2023 10:30:06
文章代碼(AID): #1ZpKGcBm (GameDesign)
文章代碼(AID): #1ZpKGcBm (GameDesign)