Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Unity,PHP+Jenkins+GAS 多言語対応を意識させない開発を目指したシステム構築

gree_tech
October 13, 2023

Unity,PHP+Jenkins+GAS 多言語対応を意識させない開発を目指したシステム構築

GREE Tech Conference 2023で発表された資料です。
https://techcon.gree.jp/2023/session/TrackB-3

gree_tech

October 13, 2023
Tweet

More Decks by gree_tech

Other Decks in Technology

Transcript

  1. 自己紹介 • 篠原 功 (Isao Shinohara) ◦ 2013年株式会社ポケラボに入社。 ◦ 「SINoALICE

    -シノアリス-」「アサルトリリィ Last Bullet」などを経て 現在は基盤チームに所属。 ◦ ローカライズやリソース管理のシステム構築を中心に 「開発・運用フローも踏まえた最適化」を目指して絶賛開発中。 2
  2. • 海外対応状況 ◦ 「SINoALICE -シノアリス-」「戦姫絶唱シンフォギア XD UNLIMITED」 などいくつかのアプリですでに海外リリース実績あり • 開発体制

    ◦ 日本版リリース後、海外版をリリース ◦ 開発チームは日本版、開発版で別チーム これまでの海外対応状況 7
  3. 連番によるID管理と翻訳間違い • 内容 ◦ 翻訳対象の日本語テキストに対し連番 IDを付与 ▪ ID:1 おはよう ▪

    ID:2 こんにちは ▪ ID:3 こんばんは ◦ 開発メンバーは日本語テキストと対応した IDを関連付ける • 課題 ◦ 日本語テキスト実装箇所は多岐に渡るので IDの関連付け作業が大変 ◦ 番号を間違えると誤った翻訳が行われる可能性がある ◦ 一度IDを割り振ったら変更することは至難 10
  4. IDを連番から日本語ハッシュ値に変更 • 内容 ◦ IDを日本語を元に生成したハッシュ値に変更 ▪ 例:) こんにちは • ID:

    1 -> ID: 20427A708C3F6… • 期待 ◦ IDの採番と関連付けのための実装が不要になる ◦ IDの割り当て間違いによる誤った翻訳が防げる 17
  5. 翻訳対象 • クライアント (Unity) ◦ シーン・プレハブ ▪ TextMeshProなどのコンポーネント ▪ SerializeField

    ◦ ソースコード (C#) ◦ ScriptableObject • サーバー (PHP, Spanner, Smarty) ◦ マスタデータ ◦ yaml ◦ ユーザーデータ ◦ WebView 23
  6. シーン・プレハブ • 対象箇所 ◦ シーン、プレハブでアタッチしている TextMeshProなどのテキストコンポーネント • 実装ルール ◦ 翻訳用のコンポーネントをアタッチ

    ▪ 翻訳不要でもアタッチ • 抽出方法 ◦ AssetDatabase.FindAssets("t:Scene t:Prefab"); ◦ GameObjectにアタッチされているテキスト コンポーネントから翻訳対象テキストを取得 • 表示処理 ◦ シーン、プレハブをアクティブにするタイミングで 各言語の翻訳テキストに置き換え 24
  7. SerializeField • 対象箇所 ◦ public stringや[SerializeField] private stringで 作成した変数にインスペクターから入力している テキスト

    • 実装ルール ◦ 使用禁止 • 理由 ◦ 翻訳対象の日本語テキストを抽出するのが難しい ◦ 翻訳処理を通しているかの保証ができない 25
  8. ScriptableObject • 対象箇所 ◦ ScriptableObject内に含まれるテキストデータ ◦ ADVパートのシナリオ管理に利用 • 実装ルール ◦

    なし • 抽出方法 ◦ ScriptableObjectファイルをロード後、 翻訳対象の日本語テキストを取得 • 表示処理 ◦ 言語毎に翻訳された JSONファイルを用意して管理 ▪ story.asset -> story_en-Latn.json, story_ko-Kore.json ▪ JsonUtility.ToJson(); ◦ 空のScriptableObjectにJSONのデータを反映 ▪ JsonUtility.FromJsonOverwrite(); 26
  9. ソースコード (C#) • 対象箇所 ◦ ソースコードに直に記述している日本語テキスト • 実装ルール ◦ 決められたクラス内に定義

    ◦ プロパティ形式にして翻訳メソッドを通す ◦ 決められたクラス以外で定義することは禁止 • 抽出方法 ◦ 決められたクラス内に存在する string or string[] を返すプロパティから翻訳対象のテキストを取得 • 表示処理 ◦ プロパティ利用時に各言語の翻訳テキストを返却 27
  10. マスタデータ • 対象箇所 ◦ Spannerで管理されている全ユーザー共通データ • 実装ルール ◦ なし •

    抽出方法 ◦ テーブルのスキーマ情報から STRING(XX)で 定義されているカラムの値を取得 • 表示処理 ◦ 言語毎に翻訳済みのマスタテーブルを用意し、 利用時に対象テーブルを切り替える ▪ ItemMst -> ItemMst_en-Latn, ItemMst_ko-Kore 28
  11. yaml • 対象箇所 ◦ yamlファイル内に記述しているテキスト • 実装ルール ◦ なし •

    抽出方法 ◦ 正規表現で「ひらがな」「カタカナ」「漢字」を 含んだテキストを抽出 ◦ 英語で記述されたテキストも翻訳対象だった ケースにどう対応するかは課題 ▪ 例:) HP, MP • 表示処理 ◦ yamlのパース処理後に対象日本語テキストを 各言語の翻訳テキストに置き換え ◦ 置き換えたyamlは言語毎にキャッシュ 29
  12. ユーザーデータ • 対象箇所 ◦ データベースにユーザー個別で記録している 日本語テキスト • 実装ルール ◦ 日本語テキストで記録

    • 抽出方法 ◦ マスタデータやyamlに記載されている 日本語テキストの場合は必要なし ◦ 上記以外の日本語テキストを利用するケースに どう対応するかは課題 • 表示処理 ◦ テーブルからデータ取得時に日本語テキストを 各言語の翻訳テキストに置き換える 30
  13. WebView • 対象箇所 ◦ テンプレートファイル内に直接記述されている 日本語テキスト ◦ テンプレートエンジンを利用してプログラムから 埋め込まれている文字列 ▪

    マスタデータやyamlに記載されている 日本語テキストの場合は必要なし • 実装ルール ◦ なし • 抽出方法 ◦ テンプレートファイル内の要素を取得 (予定) • 表示処理 ◦ テンプレート内に直接記述されている 日本語テキストはロード時に各言語の翻訳テキスト へと置き換える(予定) 31
  14. 「やってはいけないこと」の厳守 • 内容 ◦ 開発メンバーが「やってはいけない」を「やってしまってはいないか?」 • 原因 ◦ 「やってはいけないこと」の対象範囲が広い ◦

    チェックツールの作成も難しい • 方針 ◦ 現場レベルで各個人に厳守していただくことを口頭でお願い ◦ 問題ひとつひとうに対して泥臭く対応 52
  15. 実装ルール • クライアント (Unity) ◦ シーンやプレハブには必ず翻訳用のコンポーネントをアタッチ ◦ テキストは決められたクラスに定義 ▪ プロパティ形式で翻訳処理を通す

    ▪ 特定クラス以外以外は使用禁止 ◦ SerializeFieldを使った日本語テキストの利用は禁止 • サーバー (PHP, Spanner, Smarty) ◦ 基本なし。ただし注意点あり。 ▪ ユーザーデータに日本語テキストを保存する場合は日本語テキストのまま ▪ yamlに定義したテキストは英語のみだと翻訳されないので注意 54
  16. 56