跳至主要內容
SheetForge

在地化試算表

一份試算表以每種語言承載你遊戲的文字:列是鍵值,欄是語言。在地化試算表在所有重要的層面上都是一份普通的 SheetForge 試算表——它的匯入、驗證、匯出、推送與往返方式都跟資料試算表完全相同——當 Unity Localization 套件(com.unity.localization)安裝後,每一次完成的匯入還會用它填入套件自己的 StringTable 集合。你的執行期程式接著就消費標準的 LocalizedString 參照,而試算表依然是唯一真實來源。

本頁談的是你遊戲的文字。產品本身的 10 種語言 UI 是另一個主題——請參閱在地化

試算表形態(@loc

一份試算表只要帶有一列 @loc 標記列,就會成為在地化試算表。如同 @overlap@style,這一列可以出現在資料上方的任何位置;它在每一欄的儲存格會標明該欄的語言代碼

@loc     |            | en             | ko          |       |
@name    | codeName   | en             | ko          | smart | comment
@type    | RecordId   | string?        | string?     | bool? | string?
@desc    | key        | source text    | Korean      |       |
         | ui.ok      | OK             | 확인        | false | Confirm button
         | ui.cancel  | Cancel         | 취소        |       |
  • RecordId 鍵值欄為必要項 — 每一列的鍵值(ui.ok)就是在地化鍵值,而分頁名稱就是 StringTable 集合名稱:一個分頁 = 一個集合。
  • 語言欄是一種字串欄,其 @loc 儲存格帶有代碼(enkopt-BR——任何近似識別碼的標記皆可;SheetForge 驗證的是拼寫形狀,而非該代碼是否真實存在,且兩欄的代碼若僅大小寫不同也會被拒絕)。請寫成 string?:未翻譯的儲存格屆時只是涵蓋缺口,而非匯入錯誤——詳見下方的涵蓋率
  • 第一欄語言欄是來源語言。 它的文字就是資料試算表參照儲存格內嵌預覽的內容,也是自動生成鍵值時所寫入的內容。
  • 兩個保留的選填欄,以名稱比對:smart(布林值——將該條目標記為 Unity Localization 的 Smart String)與 comment(字串——同步進條目的備註中繼資料)。存在時,試算表就是這些欄位的權威來源;不存在時,橋接會讓對應的表格中繼資料維持原樣。保留欄不可同時帶有語言代碼。
  • 至少需要一個語言代碼,且一份試算表不能同時是 enum 試算表又是在地化試算表(@enum + @loc 是衝突錯誤,只回報一次)。

其餘部分都是普通試算表:暫存與 Ctrl+Z、結構編輯、@style 分組、xlsx 與 Google 往返、推送,以及網頁應用,全都把它當成一般表格處理。改變的是輸出:在地化分頁不會產生記錄類別、不會產生 Database ScriptableObject,也不會有 Addressables 位址。取而代之,它會餵給兩樣東西——鍵值常數橋接

從資料試算表參照文字(LocRef@Tab

資料試算表用一個 LocRef 參照欄指向一筆在地化條目:

@name    | codeName    | displayName
@type    | RecordId    | LocRef@Strings
@desc    | unique key  | shown in UI
         | item.sword  | item.sword.name

LocRef@Strings 的行為與你已經熟悉的內建參照(RecordId@Tab)完全相同:

  • 匯入時進行完整性驗證 — 在 Strings 分頁中不存在的鍵值會是一個附最接近候選建議的結構化錯誤;拼字錯誤在匯入時就會死掉,而不是在執行期。目標必須是一份在地化試算表(否則為 LocRefTargetNotLocalizationSheet),而沒有 @Target 的裸 LocRef 會被拒絕,並附上正確拼法的建議。
  • 完整的參照機制 — 可搜尋的鍵值選取器、鍵值重新命名傳播(重新命名一個鍵值會在同一批次中改寫每一個參照它的儲存格)、記錄畫布上的圖形邊、匯出的下拉選單規則,以及孤兒偵測,全都能運作,編輯器與網頁應用皆然。
  • 與任何參照一樣可以組合List<LocRef@Strings> 與選填形式 LocRef@Strings?(空白儲存格即為空參照)皆可運作。
  • 儲存格顯示的是文字,而不只是鍵值。 LocRef 儲存格會內嵌預覽該條目的來源語言文字,所以一份滿是鍵值的試算表讀起來依然像一句句完整的句子。記錄畫布也一樣——參照列會附帶來源文字,被截斷的值總能在工具提示中看到全文。
  • 在空白儲存格中輸入文字即可生成條目。 把來源文字打進一個空白的 LocRef 儲存格,SheetForge 會以一個手勢、一個復原步驟暫存:目標在地化試算表中的一個新鍵值(依記錄與欄位名稱建議命名——之後可自由重新命名,傳播機制會讓每一個參照保持完整)、你所輸入的文字作為其來源語言值,以及你輸入所在儲存格中的參照。兩個主機皆可。

落在你程式碼裡的內容

程式碼產生器會把該欄位輸出為 LocRef ——一個純粹可序列化的結構(目標表格與鍵值),它存在於 SheetForge 執行期組件中,無論是否安裝 Unity Localization 套件都能編譯;產生的程式碼與烘焙後的 ScriptableObject 絕不會包含套件型別。套件安裝後,一個擴充呼叫即可橋接進去:

var text = definition.displayName.ToLocalizedString(); // UnityEngine.Localization.LocalizedString

ToLocalizedString() 只有在套件存在時才會出現(一個版本定義 SHEETFORGE_LOCALIZATION 會開啟這層擴充——與 SHEETFORGE_ADDRESSABLES 所用的機制相同)。沒有套件時,該欄位仍然是一組格式完好的表格/鍵值配對,你可以自行消費。

匯入會產生什麼

除了一般輸出之外,一次匯入還會為整個專案寫入一個 SheetForgeLocalizationKeys.cs ——每個在地化分頁對應一個靜態類別(StringsKeys、……),每個鍵值持有一個 public const string,這樣遊戲程式碼就能寫 StringsKeys.ui_ok,而不是裸的 "ui.ok",同時獲得編譯期安全性與 IDE 自動完成。

  • 成員名稱是把鍵值淨化為 C# 識別碼(ASCII 字母、數字與 _ 以外的字元都會變成 _;碰撞會得到一個確定性的數字後綴)。若你想要可用的常數,請讓鍵值保持 ASCII——完全非 ASCII 的鍵值會淨化成一團底線。
  • 如同試算表定義的 enum 檔案,常數檔案是專案層級的輸出,永遠會落在設定所指定的產生程式碼資料夾中——功能與限制中同樣的組件備註也適用。
  • 沒有任何列的在地化分頁會保留一個空類別,所以清空一份試算表不會弄壞參照該型別的程式碼。

Unity Localization 橋接

套件安裝後,SheetForge 會為每個在地化分頁維護一個 StringTable 集合——鍵值、值,以及當那些欄存在時的 smartcomment 資訊。

  • 執行時機: 自動——在一次匯入完成的當下,與 Export 及 Push 作為出口所具有的地位相同——外加一個手動重新同步動作,可隨需執行。
  • 方向: 單向,試算表 → 表格。試算表是權威來源;表格是輸出結果。
  • 語言: 試算表中若有語言在專案裡找不到對應的 Locale 資源,會自動建立,並在報告中具名列出。只存在於專案中的語言則會維持原樣,並回報為未被試算表涵蓋
  • 鍵值重新命名不會弄斷場景參照。 在 Data Studio 中重新命名一個鍵值,走的是每個參照都會用到的同一套重新命名機制,橋接會就地重新命名表格條目、保留其內部 id——場景或預製件中的 LocalizedString 綁定的是那個 id,因此能在重新命名後存活。誠實的邊界: 在 Studio 之外進行的重新命名——直接在 Google 試算表或 Excel 中編輯試算表來源——與刪除一個鍵值再新增另一個是無法區分的。橋接會建立一個全新的條目(新 id),並把舊的那個視為孤兒;指向舊條目的場景參照會繼續指向那個孤兒。請在 Studio 中重新命名鍵值。
  • 試算表未建模的中繼資料一律會被保留。 備註(當沒有 comment 欄時)、排除旗標,以及任何其他表格中繼資料,都會原封不動地通過每一次同步。

外部編輯一律會被詢問,絕不靜默合併

橋接會為自己擁有的表格蓋上戳記,並記住上一次同步的指紋。如果某個表格自那之後被改動過——有人在 Localization Tables 視窗中編輯了它,或是用 Unity 自己的 Google Sheets 擴充功能拉取了內容進去——下一次同步就會停下來詢問:要從試算表覆寫,還是連同差異報告一起中止。這裡沒有靜默合併,也沒有靜默覆寫。如果你想要雙駕駛座的工作流程,請改成讓另一個駕駛座透過試算表繞道而行——這正是翻譯匯出的用途。

孤兒鍵值預設會被保留

存在於表格中、卻已不在試算表裡的鍵值是一個孤兒:它會被保留、列在孤兒報告中,並可透過明確的清理動作移除(一次全部或逐一移除)。若你想要表格完全鏡射試算表,有一個設定開關可以切換成同步時刪除。沒有任何東西會作為副作用被摧毀。

沒有套件時

Unity Localization 套件是選用的。沒有它:

  • 在地化試算表依然是完整的試算表——編寫、驗證、涵蓋率、Export、Push、xlsx、網頁應用、鍵值常數與 LocRef 欄位全都完整可用。
  • 唯一會等待的是 StringTable 同步出口,它會顯示安裝提示(每個工作階段一次)並停止——與 Addressables 相同的引導模式,同樣絕不會以程式化方式安裝。
  • 每個組件、每一行產生的程式碼,在沒有套件的情況下都能編譯。支援的套件版本:1.5 以上

把既有的表格遷移進試算表

已經在用 Unity Localization 了嗎?一個反向匯入器能把既有的 StringTable 集合轉換成一份在地化試算表,直接寫入你的匯入來源並自動匯入——與建立試算表所走的是同一條路徑。檢閱與修改都放在那之後,就跟其他任何試算表一樣。如果目前作用中的匯入來源無法從編輯器寫入,檔案會落在 Export 輸出的旁邊,並附上一則提示要你把它移過去。當橋接之後把那份試算表同步回同一個集合時,條目 id 會依鍵值名稱比對繼承——場景與預製件中既有的 LocalizedString 參照能完好無損地撐過這次遷移。

翻譯工作流程

涵蓋率:未翻譯的儲存格會被回報,而不是被拒絕

空白的語言儲存格不是錯誤——匯入會回報逐語言涵蓋率(每種語言翻譯了多少鍵值、又缺少哪些),而每一個出口都維持開放。文字是逐步到位的;試算表絕不會因為一項未完成的翻譯而卡住。

語言檢視鏡

一次只想處理一種語言?語言檢視鏡可以切換哪些語言欄是可見的。它是 @style 家族中的顯示中繼資料——絕不會觸及匯入指紋、程式碼產生,或任何輸出。兩個主機皆可。

翻譯匯出與部分重新匯入

要把一種語言交給譯者,就匯出一份翻譯活頁簿:挑選語言,取得一份含鍵值+來源文字+備註+狀態欄的 xlsx,其中自上次匯出以來來源文字有變動的條目會被標記為過時。檔案送回後,以部分合併的方式重新匯入:列依鍵值比對,且只會寫入語言欄——結構、其他語言與試算表中的其餘一切都維持不變。兩個主機皆可。 有一處誠實的不對稱:狀態記憶保存在 Unity 專案旁的本機檔案中,因此從瀏覽器匯出的活頁簿其狀態欄始終為 new;重新匯入時「以舊來源文字為準的翻譯」提示比較的是檔案自身攜帶的來源文字,所以在兩個主機皆可運作。

XLIFF 與偽語言

SheetForge 刻意重新實作 XLIFF 或偽在地化——橋接所填入的表格是普通的 Unity Localization 表格,所以套件自己的 XLIFF 匯出/匯入與偽語言工具,在這些表格上運作起來就跟在任何專案上一樣。不過請記得單向的權威關係:工具寫表格的輸出,屬於下一次同步會詢問的外部編輯。要讓翻譯留在唯一真實來源裡,請透過試算表(上面的翻譯活頁簿)把它們帶回來,而不是寫進表格裡。

誠實說明兩個相關的邊界:橋接只涵蓋字串表格——資源表格是一項已承認的待辦事項——而且 SheetForge 不隨附任何語言專屬的 Smart Format 輔助工具(例如韓文的助詞選擇)。smart 欄會把條目標記為 Smart String;超出套件內建範圍的格式化工具,就要由你透過套件自己的擴充點來撰寫。

在網頁應用中

在瀏覽器中,在地化試算表就是一份普通的試算表:編寫、驗證、涵蓋率、附內嵌來源文字的 LocRef 選取器、鍵值生成、語言檢視鏡,以及翻譯活頁簿,在 web.sheetforge.workers.dev 全都能運作。StringTable 同步是 Unity 編輯器的工作——瀏覽器沒有 Unity 專案可以把表格寫進去,它也不會假裝自己可以。

相關頁面