🙄

【UE4】OneSkyとGoogleスプレッドシートを使ってpoファイルを作成する方法

2022/04/10に公開

OneSky(翻訳サービス)の説明

https://www.oneskyapp.com/
翻訳依頼をしなければ無料で使えます。

OneSkyの画面

  • 「翻訳の概要」 > 「翻訳をダウンロード」から翻訳データを色々なファイル形式で落とせます。
  • 「ファイル」の項目ではCSVやpoなどの翻訳データをアップできます。

OneSky上でスプレッドシートの翻訳データの読み込ませたい場合

https://support.oneskyapp.com/hc/en-us/articles/206709057-Uploading-phrases-using-spreadsheet-Excel-file-

OneSkyからpoファイルをエクスポートしたけど失敗

UE4との連携方法(APIを使う方法)がわからなかったので、以下を試しました。

  1. OneSkyにCSVの翻訳データ(英語、日本語など)をアップ
  2. poファイルとしてエクスポート
  3. エクスポートしたpoファイルをUE4にインポート

結果は失敗...。

poって何?っていう方はこちらをご覧になってください。
https://historia.co.jp/archives/13223/

なぜ失敗したのか

OneSkyからエクスポートしたpoファイルを開いてみたら、構成要素である 「msgctxt」 がすっぽり抜け落ちていました。
これだとUE4に正しくインポートすることができません。

しかし、OneSkyで取得した情報は使えるのでこれと、GAS(Google Apps Script)を使って、poファイルを作成することにしました。

※GASのコードはコピペできるように下に貼ってあるので、自己責任でお使いください。

OneSkyとスプレッドシート使ってpoファイルを作る流れ

  1. 翻訳元となる基本言語をOneSkyで読み込ませます。UE4から出力したpoファイルをそのまま読み込ませればOKです。

  2. 読み込ませた基本言語をエクセルかCSV形式でエクスポート。

  3. エクスポートしたデータをスプレッドシートにインポートし、「String Identifier」 の情報を取得。

  1. 「String Identifier」の列と翻訳言語の列で構成されたスプレッドシートを作成。
  1. スプレッドシート上でpoファイルを作成するため、GASを使う。

    「Apps Script」より、スプレッドシートに対してプログラムを書くことが可能です。

GASを使ってpoファイル作成(コピペ用コード記載)

/**
 * スプレッドシートの内容をPoファイルへ出力
 * 
 * poファイルの中身の例
 * msgctxt "GameMsg,GameMsg_Ohayo"
 * msgid "GameMsg_Ohayo"
 * msgstr "おはよう。/n"
 * "今日も良い天気ですね。"
 */
function outputPoFile() {

  // 出力するフォルダのID('XXX'の部分は出力先のフォルダIDを設定)
  const folderId = 'XXX';

  // 選択中のシートを取得
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  // 選択中のセルを取得(英語のpoファイルがほしいなら英語列の先頭のセルを選択)
  let currentCell = sheet.getActiveCell();

  // 出力するファイル名
  const fileName = sheet.getSheetName() + `_` + currentCell.getValue() + '.po';
  
  // Poに出力する範囲のデータを取得(A列に入力されているデータを2行目から取得)
  let values = sheet.getRange(2, 1, sheet.getLastRow() - 1).getValues();

  // Poに出力する範囲のデータを取得(選択中の列に入力されているデータを2行目から取得)
  let locTarget = sheet.getRange(2, currentCell.getColumn(), sheet.getLastRow() - 1).getValues();

  // Poファイルの中身
  let contents = '';

  for(let i = 0; i < values.length; i++) {
    let splitText = values[i][0].split(".");
    contents += 'msgctxt ' + '"' + splitText[1] + '"' + "\n";
    contents += 'msgid ' + '"' + splitText[0] + '"' + "\n";
    splitText = locTarget[i][0].split("\n");
    if(splitText.length > 1){
      for(let j = 0; j < splitText.length; j++) {
        if(j == 0){
          contents += 'msgstr ' + '"' + splitText[0] + '\\r\\n"' + "\n";
        } else if(j == splitText.length - 1) {
          contents += '"' + splitText[j] + '"' + "\n";
        } else {
          contents += '"' + splitText[j] + '\\r\\n"' + "\n";
        }
      }
    } else {
      contents += 'msgstr ' + '"' + locTarget[i][0] + '"' + "\n";
    }
    contents += "\n";
  }

  // Poファイル書き出し
  createTextFile(folderId, fileName, contents);
}

/**
 * Poファイル書き出し
 * @param {string} folderId フォルダID
 * @param {string} fileName ファイル名
 * @param {string} contents ファイルの内容
 */
function createTextFile(folderId, fileName, contents) {  

  // コンテンツタイプ
  const contentType = 'text/plain';
  
  // 文字コード
  const charset = 'UTF-8';

  // 出力するフォルダ
  const folder = DriveApp.getFolderById(folderId);

  // Blob を作成する
  const blob = Utilities.newBlob('', contentType, fileName).setDataFromString(contents, charset);

  // ファイルに保存
  folder.createFile(blob);
}

まとめ

翻訳はスプレッドシートで管理してもpoファイルに変換する方法がなかったので、UE4にインポートできなかったのですが、これで翻訳をスプレッドシートで管理しつつスプレッドシート上でpoファイルが作成できるようになりました。
ただ、その際にはpoファイルの構成要素の「msgctxt」「msgid」の情報を一覧で取得している必要があります。
今回は、その情報はOneSkyを使って「String Identifier」として取得しています。
もしかしたらOneSkyを使わなくても「msgctxt」「msgid」を一覧で取得する別の方法があるかもしれません。
poファイルがもう少し扱いやすくなってくれたらいいなぁと思います。

Discussion