로컬라이제이션 스크립팅

로컬라이제이션 테이블에 번역을 추가하여 자동으로 처리할 수 없는 전문 번역 작업에 대해서는 로컬라이제이션 API를 사용할 수 있습니다. Roblox는 로컬라이제이션이 필요한 모든 스크립팅을 위해 LocalizationService를 제공합니다. LocalizationService는 다음과 같은 작업에 사용할 수 있습니다.

체험을 번역할 때 로컬라이제이션 API를 사용하는 경우, 체험에 있는 동안 언어를 변경하는 사용자들에 제대로 반응할 수 있도록 사용자의 LocaleID가 바뀌는지 모니터링해야 합니다.

번역 코드를 재사용할 때는 TranslationHelper ModuleScript를 사용하여 오류와 누락된 번역을 처리해야 합니다.

이미지 및 사운드 로컬라이제이션

사용자의 로캘에 따라 독특한 이미지와 소리를 제공함으로써 체험에서 텍스트 이외의 항목에도 로컬라이제이션을 적용할 수 있습니다. 애셋을 로컬라이즈하려면 먼저 체험의 로컬라이제이션 테이블소스타깃 애셋 ID를 추가한 다음 로컬라이제이션 API를 사용하여 다른 애셋을 가져옵니다.

영어(소스) - rbxassetid://2957093606
스페인어(es) - rbxassetid://2957093671
포르투갈어(pt) - rbxassetid://2957093727

이미지 및 사운드에 대한 로컬라이제이션을 시작하려면 로컬라이제이션 테이블에 소스타깃 애셋 ID를 추가합니다. 로컬라이제이션 테이블의 애셋 ID 항목에는 API가 호출하는 식별자인 가 들어 있어야 합니다. 아래에는 로컬라이제이션 테이블에서 애셋 ID를 사용한 입력 항목의 예가 나와 있습니다.

소스espt
Key_JewelsImage295709360629570936712957093727

다음의 코드는 ImageLabel의 애셋 ID를 로컬라이제이션 테이블에 제공된 스페인어 애셋 ID로 변경해 줍니다.


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalizationService = game:GetService("LocalizationService")
-- Local variables
local localizedImageID
local localizedImage = Instance.new("ImageLabel")
-- Load Translator for "es". Wrap the function within a pcall() to protect against failures.
local res, translator = pcall(function()
return LocalizationService:GetTranslatorForLocaleAsync("es")
end)
if res then
-- Get asset ID from localization table by referencing the Key
localizedImageID = translator:FormatByKey("Key_JewelsImage")
-- Set the image
localizedImage.Image = "rbxassetid://" .. localizedImageID
else
print('GetTranslatorForPlayerAsync failed: ' .. translator)
end

개별 문자열 번역

상황에 따라 개별 문자열을 타깃으로 번역하고 싶은 경우도 있습니다. Translator:Translate()은 소스 문자열을 기반으로 로컬라이제이션 테이블에서 개별 항목을 가져옵니다.

아래 예에서는 다음과 같은 로컬라이제이션 항목이 사용됩니다.

소스esespt
ScreenPantalla2950936712957093727

아래의 스크립트는 'Screen'이란 단어의 스페인어 번역을 출력 창에 표시합니다.


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalizationService = game:GetService("LocalizationService")
-- Load Translator for "es". Wrap the function within a pcall() to protect against failures.
local res, translator = pcall(function()
return LocalizationService:GetTranslatorForLocaleAsync("es")
end)
if res then
-- Use Translate function, providing object context and string
local sourceTranslation = translator:Translate(game, "Screen")
print(sourceTranslation) -- Expected Output: "Pantalla"
else
print('GetTranslatorForPlayerAsync failed: ' .. translator)
end

콘텍스트 재정의 사용

같은 문자열이 여러 의미를 갖고 있는 경우도 있습니다. 예를 들어, 영어 단어 'Screen'은 컴퓨터 화면을 의미할 수도 있고 창문의 방충망을 표현할 때도 쓰입니다. 따라서 이 단어는 여러 개의 완전히 다른 스페인어 번역을 갖고 있습니다.

로컬라이제이션 테이블의 콘텍스트 열은 콘텍스트 재정의를 통해 번역을 구체적으로 지정하는 데 사용합니다. 아래의 예와 같이 로컬라이제이션 테이블에서 게임 내 개체를 지정할 수 있습니다.

문맥소스es
workspace.WindowScreen.SurfaceGui.TextLabelScreenMosquitero
ScreenPantalla

아래의 스크립트는 구체적인 번역을 우선시하기 위해 콘텍스트 재정의를 사용합니다.


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalizationService = game:GetService("LocalizationService")
-- Load Translator for "es". Wrap the function within a pcall() to protect against failures.
local res, translator = pcall(function()
return LocalizationService:GetTranslatorForLocaleAsync("es")
end)
if res then
-- use Translate function, providing object context and string
local sourceTranslation = translator:Translate( workspace.WindowScreen.SurfaceGui.TextLabel, "Screen")
print(sourceTranslation) -- Expected Output: Mosquitero
else
print('GetTranslatorForPlayerAsync failed: ' .. translator)
end

복수 콘텍스트

복수 콘텍스트의 경우, 로컬라이제이션 서비스는 콘텍스트 필드에서 개체 관계를 오른쪽부터 왼쪽으로 비교하여 가장 가까운 일치 항목을 사용합니다.

예를 들어, 체험의 로컬라이제이션 테이블에는 다음과 같은 소스를 공유하는 문자열 항목이 존재할 수 있습니다.

문맥소스es
workspace.WindowScreen.SurfaceGui.TextLabelScreenMosquitero
playerGui.ScreenGui.TextButtonScreenPantalla

체험의 playerGui.ScreenGui.TextLabel 개체에 'Screen' 문자열이 추가되면 로컬라이제이션 서비스는 스페인어 번역에서 가장 가까운 콘텍스트 일치 항목으로 'Mosquitero'를 표시합니다.

매개 변수 활용

매개 변수를 사용하여 다이내믹 콘텐츠를 번역할 때는 테이블에 값을 설정하고 API를 통해 이 테이블을 인수로 전달합니다.

이 예에서는 체험의 로컬라이제이션 테이블에 다음과 같은 항목이 들어 있습니다.

소스es
Key_Prize_1보석 {1:int}{1:int} joyas
Key_Prize_2현금 ${AmountCash:fixed} 및 보석 {NumJewels:int}${AmountCash:fixed} dinero y {NumJewels:int} joyas

다음과 같은 코드 샘플을 사용하여 매개 변수 값이 있는 이러한 문자열을 번역할 수 있습니다.


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalizationService = game:GetService("LocalizationService")
-- Load Translator for "es". Wrap the function within a pcall() to protect against failures.
local res, translator = pcall(function()
return LocalizationService:GetTranslatorForLocaleAsync("es")
end)
if res then
-- Set the parameter value in "Key_Prize_1" to 100
local keyTranslation1 = translator:FormatByKey("Key_Prize_1", {100})
print(keyTranslation1) -- Expected Output: 100 joyas
-- Set multiple parameters to 500 and 100 by name
local keyTranslation2 = translator:FormatByKey("Key_Prize_2", {AmountCash=500, NumJewels=100})
print(keyTranslation2) -- Expected Output: $500.00 dinero y 100 joyas
else
print('GetTranslatorForPlayerAsync failed: ' .. translator)
end

언어 변경

경우에 따라 체험 내에서 다른 언어 번역을 표시하고 싶을 때가 있습니다. LocalizationService:GetTranslatorForLocaleAsync()를 사용하여 다른 국가 코드를 가진 새로운 번역기를 설정할 수 있습니다.

다음의 코드 샘플은 수동 입력 국가 코드를 사용하는 한 개의 번역기와 사용자의 글로벌 로캘 설정을 기반으로 하는 추가 번역기를 설정합니다.


local ReplicatedStorage = game:GetService("ReplicatedStorage")
local LocalizationService = game:GetService("LocalizationService")
local Players = game:GetService("Players")
-- Local variables
local player = Players.LocalPlayer
-- Load Translator for "pt". Wrap translator functions within a pcall() to protect against failures.
local res1, translator = pcall(function()
return LocalizationService:GetTranslatorForLocaleAsync("pt")
end)
-- Load second Translator with Player's locale, in this example "es"
local res2, fallbackTranslator = pcall(function()
return LocalizationService:GetTranslatorForPlayerAsync(player)
end)
-- Use Translate function with first Translator
if res1 then
local translate1 = translator:Translate(game, "jewels")
print(translate1) -- Expected Output in pt: joyas
else
print('GetTranslatorForPlayerAsync failed: ' .. translator)
end
-- Use Translate function with second Translator
if res2 then
local translate2 = fallbackTranslator:Translate(game, "jewels")
print(translate2) -- Expected Output in if user is set to 'es': jóias
else
print('GetTranslatorForPlayerAsync failed: ' .. fallbackTranslator)
end

언어를 변경하는 사용자에 반응하기

사용자는 언제든지 체험 내 설정 메뉴를 사용하여 언어 설정을 변경할 수 있습니다. 사용자가 이렇게 설정을 변경하면 자동 번역이 처리하는 문자열 등과 같이 스크립팅이 아닌 로컬라이제이션 애셋이 자동으로 업데이트됩니다. 그러나 GUI 이미지나 소리와 같이 이미 렌더링된 스크립트 로컬라이제이션 변경은 업데이트되지 않을 수 있습니다.

체험 내 언어 설정
사용자가 체험에서 사용할 수 있는 언어 선택

스크립트 기반의 로컬라이즈된 애셋이 제대로 업데이트되도록, LocalizationService.GetTranslatorForPlayerAsync가 반환하는 Translator 인스턴스의 LocaleID 속성이 변경되었음을 알리는 GetPropertyChangedSignal 이벤트를 모니터링해야 합니다. LocalizationService.GetTranslatorForPlayerAsync를 사용할 때 오류가 발생하면 pcall 안에서 함수를 래핑하세요.

아래의 코드 샘플은 사용자가 언어를 변경할 때 사용자의 로캘 ID와 이 사용자에 대한 번역기 인스턴스의 로캘 ID를 표시합니다.


local LocalizationService = game:GetService("LocalizationService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- If GetTranslatorForPlayerAsync succeeds, it will return a Translator for player's current locale
local res, translator = pcall(function()
return LocalizationService:GetTranslatorForPlayerAsync(player)
end)
-- Function that gets called when change in player's locale ID is detected
local function OnLocaleIdChanged()
print("Translator has changed to: " .. translator.LocaleId)
-- You should re-translate any assets translated with Localization APIs to the player's new language here
end
-- Check if GetTranslatorForPlayerAsync succeeded
if res then
-- If succeeded, translate assets here using translator
-- Listen for a change in player's locale ID
translator:GetPropertyChangedSignal("LocaleId"):Connect(OnLocaleIdChanged)
else
print('GetTranslatorForPlayerAsync failed: ' .. translator)
end

TranslationHelper 모듈 만들기

플레이어의 기본 로캘을 기반으로 번역기를 불러올 때 코드를 재사용할 수 있습니다. 코드를 재사용하려면 플레이어의 기본 로캘에 따라 안전하게 번역기를 불러오고 구체적인 번역 제공과 언어 변경을 위한 함수를 포함하는 도우미 ModuleScript를 설정하세요.

다음의 코드 샘플이 실행하는 TranslationHelper는 ReplicatedStorageModuleScript로 본인의 프로젝트에 복사하여 사용할 수 있습니다.


local TranslationHelper = {}
local LocalizationService = game:GetService("LocalizationService")
local Players = game:GetService("Players")
-- Local variables
local player = Players.LocalPlayer
local sourceLanguageCode = "en"
-- Get translators
local playerTranslator, fallbackTranslator
local foundPlayerTranslator = pcall(function()
playerTranslator = LocalizationService:GetTranslatorForPlayerAsync(player)
end)
local foundFallbackTranslator = pcall(function()
fallbackTranslator = LocalizationService:GetTranslatorForLocaleAsync(sourceLanguageCode)
end)
-- Create a method TranslationHelper.setLanguage to load a new translation for the TranslationHelper
function TranslationHelper.setLanguage(newLanguageCode)
if sourceLanguageCode ~= newLanguageCode then
local success, newPlayerTranslator = pcall(function()
return LocalizationService:GetTranslatorForLocaleAsync(newLanguageCode)
end)
--Only override current playerTranslator if the new one is valid (fallbackTranslator remains as experience's source language)
if success and newPlayerTranslator then
playerTranslator = newPlayerTranslator
return true
end
end
return false
end
-- Create a Translate function that uses a fallback translator if the first fails to load or return successfully. You can also set the referenced object to default to the generic game object
function TranslationHelper.translate(text, object)
if not object then
object = game
end
local translation = ""
local foundTranslation = false
if foundPlayerTranslator then
return playerTranslator:Translate(object, text)
end
if foundFallbackTranslator then
return fallbackTranslator:Translate(object, text)
end
return false
end
-- Create a FormatByKey() function that uses a fallback translator if the first fails to load or return successfully
function TranslationHelper.translateByKey(key, arguments)
local translation = ""
local foundTranslation = false
-- First tries to translate for the player's language (if a translator was found)
if foundPlayerTranslator then
foundTranslation = pcall(function()
translation = playerTranslator:FormatByKey(key, arguments)
end)
end
if foundFallbackTranslator and not foundTranslation then
foundTranslation = pcall(function()
translation = fallbackTranslator:FormatByKey(key, arguments)
end)
end
if foundTranslation then
return translation
else
return false
end
end
return TranslationHelper

모듈이 ReplicatedStorage에 있으면 LocalScript에서 이를 요청하여(require 함수) 이 모듈의 함수를 호출합니다. 다음의 코드는 이 모듈의 도우미 함수를 사용하여 개별 문자열을 번역합니다.


local ReplicatedStorage = game:GetService("ReplicatedStorage")
-- Require translation module
local TranslationHelper = require(ReplicatedStorage:WaitForChild("TranslationHelper"))
-- Use the functions provided in TranslationHelper
TranslationHelper.setLanguage("es")
local sourceTranslation = TranslationHelper.translate("Screen")
print(sourceTranslation) -- Expected Output in 'es': "Pantalla"