おことわり
この記事には、新しい版 (GitHub)が存在します。
はじめに
- この記事は、過去に公開した記事の焼き直しで、以下の相違があります。
-
ScriptableObject
とAddressables
に対応しました。 - スプレッドシート側の計算式を使わずに、シート全体を取得して解析するようしました。
-
- 公開当初に比して、以下の点が変更されました。
- unity 2020.3で確認しました。
- OAuth 2.0に対応しました。
- Windowsに依存した可能性が高いです。
前提
- unity 2020.3.30f1
- Addressables 1.18.19
- Googleスプレッドシート
- Googleアカウント
- Windows 10
- 他のOSではテストされておらず、動作は不明です。
このシステムのセキュリティについて
- このシステムのセキュリティ
- スプレッドシート
- 特別な共有設定は不要で、共同編集者のGoogleアカウントに対する共有のみを設定します。
- ドキュメントIDが、平文でエディターの設定内(EditorPrefs)に保存されます。
- Google Apps Script
- 自分のみが使えるように設定します。
- 承認したGoogleアカウントの権限で実行され、承認者がアクセス可能な全てのスプレッドシートにアクセス可能です。
- アプリケーションのURLが、平文でエディターの設定内(EditorPrefs)に保存されます。
- Google Cloud Platform
- クライアント ID、クライアント シークレット、アクセストークン、リフレッシュトークンが、平文でエディターの設定内(EditorPrefs)に保存されます。
- スプレッドシート
できること
- 言語別テキストや定数などをGoogleスプレッドシートで共同編集できます。
- 「シナリオやユーザー向けメッセージなどの編集者」や「各種の初期値を設定する担当者」がプログラマーでない場合に共同制作が容易になります。
- 多言語対応のテキストと、言語に依存しない固定値 (int、float、string、bool)を扱えます。
- 編集結果は、任意のタイミングでプロジェクトへ取り込むことができます。
- ビルド番号を管理できます。
- スクリプトから定数として参照できます。
- ビルド毎に自動更新できます。
- プラットフォーム毎の番号を統一できます。
特徴
- 取り込んだスプレッドシートの情報を、C#スクリプトと言語別ScriptableObjectに変換します。
- ScriptableObjectはAddressablesで管理されます。
- スプレッドシートの取り込みは、別スレッドで実行され、エディターをブロックしません。
導入
クラウドの準備
Google Apps Script の作成
- The Apps Script Dashboardへアクセスします。
- 「新規スクリプト」を作成します。仮に、
getspreadseet2
と名付けたものとします。 - 「コード.gs」の中身を、以下のコードで置き換えます。
getspreadseet2/コード.gs
// getspreadseet?d=document&s=seet&a=area
function doGet(e) {
if (e.parameter.d != null) {
var spreadsheet = SpreadsheetApp.openById(e.parameter.d);
if (e.parameter.w == null) { // 読み出し
if (e.parameter.a != null) { // セル
var value = spreadsheet.getSheetByName(e.parameter.s).getRange(e.parameter.a).getValue();
Logger.log (value);
return ContentService.createTextOutput(value).setMimeType(ContentService.MimeType.TEXT);
} else if (e.parameter.s != null) { // シート
var values = spreadsheet.getSheetByName(e.parameter.s).getDataRange().getValues();
Logger.log(values);
return ContentService.createTextOutput(JSON.stringify(values)).setMimeType(ContentService.MimeType.TEXT);
} else if (e.parameter.id != null) { // シートID一覧
var sheets = spreadsheet.getSheets();
var sheetids = [sheets.length];
for (var i = 0; i < sheets.length; i++) {
sheetids [i] = sheets [i].getSheetId();
}
Logger.log(sheetids);
return ContentService.createTextOutput(JSON.stringify(sheetids)).setMimeType(ContentService.MimeType.TEXT);
} else { // シート名一覧
var sheets = spreadsheet.getSheets();
var sheetnames = [sheets.length];
for (var i = 0; i < sheets.length; i++) {
sheetnames [i] = sheets [i].getName();
}
Logger.log(sheetnames);
return ContentService.createTextOutput(JSON.stringify(sheetnames)).setMimeType(ContentService.MimeType.TEXT);
}
} else { // 書き込み
if (e.parameter.a != null) { // セル
spreadsheet.getSheetByName(e.parameter.s).getRange(e.parameter.a).setValue(e.parameter.w);
} else if (e.parameter.s != null) { // シート
var sheet = spreadsheet.getSheetByName(e.parameter.s);
if (sheet != null) {
sheet.getDataRange().clear();
} else {
sheet = spreadsheet.insertSheet(e.parameter.s);
}
//return ContentService.createTextOutput(e.parameter.w).setMimeType(ContentService.MimeType.TEXT);
var values = JSON.parse(e.parameter.w);
sheet.getRange(1,1,values.length,values[0].length).setValues(values);
sheet.autoResizeColumns (1, values[0].length);
if (e.parameter.r != null) {
sheet.setFrozenRows(e.parameter.r);
}
if (e.parameter.c != null) {
sheet.setFrozenColumns(e.parameter.c);
}
}
}
}
return ContentService.createTextOutput("[]").setMimeType(ContentService.MimeType.TEXT); // 空
}
function doPost (e) {
return doGet (e);
}
- 「デプロイ」から「新しいデプロイ」を選び、以下を選択します。
- 次のユーザーとしてアプリケーションを実行:
自分(~)
- アクセスできるユーザー:
自分のみ
- 次のユーザーとしてアプリケーションを実行:
- 「デプロイ」ボタンを押します。
- デプロイする際には、先ず承認が必要です。
- デプロイできたら、《ウェブ アプリケーションの URL》を控えておきます。
- 後からでも、「デプロイの管理」から確認できます。
Google Cloud Platform の作成
- Google Cloud Platformのダッシュボードへアクセスします。
- 「APIとサービス」→「OAuth 同意画面」で、同意画面を作ります。
- 初めてなら、まず、プロジェクトを作ることになります。
- 「テストユーザー」に自分を追加します。
- 「認証情報」に切り替えて、「OAuth クライアント ID」を作成します。
- 「アプリケーションの種類」は「デスクトップアプリ」にします。
- 《クライアント ID》と《クライアント シークレット》を控えます。
- 後からでも、「認証情報」から確認できます。
スプレッドシートの用意
- スプレッドシートの雛形を開き、ファイルメニューから「コピーを作成…」を選びます。
- フォルダを選んで保存します。
- Googleドライブに保存されます。
- マイドライブから保存したフォルダへ辿り、コピーされたスプレッドシートを開きます。
- 開いたスプレッドシートのURLで、
https://docs.google.com/spreadsheets/d/~~~/edit
の「/d/~~~/」の部分に注目してください。- この「~~~」の部分が、このスプレッドシートの《ドキュメントID》です。
- このIDは、後で使用しますので、何処か安全な場所に控えておいてください。
Unityプロジェクトの準備
アセットの入手と導入 (GitHub)
- こちらのリポジトリをベースにするものと想定します。
設定
- 「Window」メニューの「GetSharedData > OPen Setting Window」を選択しウインドウを開きます。
- 「Document ID」に、控えておいた《ドキュメントID》を記入します。
- 「Asset Folder」は、プロジェクトのフォルダ構造に合わせて書き換え可能です。
- 「Application URL」に、控えておいた《ウェブ アプリケーションの URL》を記入します。
- 後からURLを確認するには、The Apps Script Dashboardの「デプロイの管理」を参照します。
- 「OAuth Settings」を開き「Client ID」と「Client Secret」に、控えておいた《クライアント ID》と《クライアント シークレット》を記入します。
- 後からIDとシークレットを確認するには、GCPダッシュボードの「認証情報」を参照します。
- 「Build Number」は、ビルド番号を取り込む機構に対する設定です。
- 「Unified Number」にチェックすると、機種毎のビルド番号を最大のものに合わせます。
- 「Auto Increment」にチェックすると、ビルド毎に自動的にビルド番号を1増やします。
- 設定はエディターを終了しても保存されます。
- プロジェクトの設定は、
Player Settings
のCompany Name
とProduct Name
で識別されるプロジェクト毎に保持されます。 - 「Application URL」は、プロジェクトを横断して保持されます。
- 全ての設定は、EditorPrefsに平文で保存されます。
- プロジェクトの設定は、
使い方
編集と取り込み
スプレッドシート
- 「Text」と「Const」は、シート名として予約されています。
- シートの追加や並び替えは任意に行うことができますが、シート名の重複はできません。
- 「Text」シートに記載したものは言語切り替えテキスト、「Const」シートに記載したものは定数に変換されます。
- 他のシートは無視されます。
- シートでは、行を3つの部分(「列ラベル」、「列ラベルより上」、「列ラベルより下」)に分けます。
- 「Key」と書かれたセルが最初に見つかった行が、列ラベルになります。
- 列ラベルより上の行は無視されます。
- 「Key」、「Type」、「Value」、「Comment」、および、
UnityEngine.SystemLanguage
で定義されている名前は、列ラベル名として予約されています。- ラベルの文字種や空白文字の有無は区別されます。
- 予約されていない名前の列は無視されます。
- セルの値(計算結果)だけが使われ、シートの計算式や書式は無視されます。
- 「Text」シートでは、「Key」および「Comment」列と、任意の数の言語名の列を記入します。
- 最も左の列の言語がデフォルトになります。
- セル内改行は、改行文字
\n
に変換されます。
- 「Const」シートでは、「Key」、「Type」、「Value」、「Comment」列を記入します。
- キーとして、「BuildNumber」、「BundleVersion」が予約されています。
Unityエディター
- GetSharedDataウィンドウの「GetSharedData」ボタンを押すか、Windowメニューの「GetSharedData > Get Spreadsheet」を選ぶか、そのメニュー項目に表示されるキーボードショートカットを使うことで、スプレッドシートの情報が取り込まれ、コンパイルされます。
Addressables
- 言語別テキストを格納したアセット
Text_言語名.asset
は、Addressablesに入れてください。- アドレスを単純化(Simplify)して、名前だけにしておいてください。
- 再取り込みを行う際は、ファイルは作り直されずに内容だけが上書きされます。
- Unityエディターで内容を編集することは想定していません。
スクリプトでの使用
-
using SharedConstant;
を指定してください。
テキスト
- システムの言語設定(
Application.systemLanguage
)に従って初期設定されます。 -
SystemLanguage Txt.Locale
言語 (プロパティ)-
SystemLanguage
型の値を代入することで、強制的に言語を切り替えます。 -
SystemLanguage.Unknown
を指定すると、システムの言語設定に従います。 - 相当する言語がアセットにない場合は、デフォルト(シート最左)の言語が使われます。
- 切り替えてから実際に値が変化するまでには、アセットをロードする時間分のラグがあります。
-
-
string Txt.S (Nam.key[, ...])
テキスト (メソッド)- キーを指定して現在設定されている言語のテキストを返します。
- キーを列挙すると該当するテキストを連結して返します。
-
string Txt.F (Nam.key, object arg[, ...])
フォーマットテキスト (メソッド)- 指定したキーをフォーマットとして他の引数を展開したテキストを返します。
-
int Txt.N (string str)
キーの逆引き (メソッド)-
Txt.S (~)
で得たテキストを渡すと、該当のキーを返します。 - 未定義なら
-1
を返します。
-
- キー
Nam.~
は、const int
として定義された文字列のインデックスです。
数値
- キーは
const
として定義されます。 -
Cns.~
として使用します。 -
Cns.BuildNumber
、Cns.BundleVersion
が自動的に定義されます。
Unity使用者が複数いる場合の留意点
- 例えば、「Unityを使わない企画者、Unityを使うデザイナとプログラマの3人」といったように、スプレッドシートからUnityに情報を取り込むメンバーが複数いる場合は以下の点に留意してください。
- メンバーで共有するアセットの設定は、「Project Settings」と「Build/Bundle Number Settings」だけです。
- 「OAuth Settings」は共有してはいけません。つまり、各メンバーそれぞれがGoogle Apps Script の作成を行う必要があります。
- なお、これらの設定は、プロジェクトのフォルダには保存されないので、GitHubなどによるアセットの共有で問題が生じることはありません。