【Cocos Creator 3.8】LocalizationMgr の実装:アタッチするだけで日本語/英語を即座に切り替える汎用スクリプト
本記事では、Cocos Creator 3.8.7 + TypeScript で、TranslationServer を制御して日本語/英語を即座に切り替える「LocalizationMgr」コンポーネントを実装します。
このコンポーネントは、任意のノードにアタッチするだけで動作し、外部の GameManager やシングルトンに依存しません。Inspector から初期言語や UI 更新のタイミングを設定できるため、シーンごとに簡単にローカライズ設定を変えられるのが特徴です。
コンポーネントの設計方針
1. 機能要件の整理
- Cocos Creator 標準の
TranslationServer(3.8 ではdirector.root?.dataPoolManager.translationServer経由)を制御する。 - 日本語 (ja) / 英語 (en) の 2 言語を即座に切り替える。
- Inspector から以下を設定できるようにする:
- 初期言語(シーン開始時に自動で設定)
- 現在の言語の表示用(エディタ確認用)
- キー入力やメソッド呼び出しでの言語切替制御
- コンポーネント単体で完結させるため、他のカスタムスクリプトには一切依存しない。
- 防御的実装として、TranslationServer が取得できない場合は
errorログを出し、処理を安全に中断する。
2. Cocos Creator 3.8 における TranslationServer へのアクセス方針
Cocos Creator 3.8 では、翻訳関連のサービスは director.root?.dataPoolManager.translationServer のような形で内部に保持されています。バージョンやビルド設定によって構造が変わる可能性があるため、以下のような方針で防御的にアクセスします。
director.rootが存在するかチェック。dataPoolManagerが存在するかチェック。translationServerが存在するかチェック。- いずれかが存在しない場合は、
errorログを出して以降の処理を行わない。
TranslationServer 側の API は、以下のような最小想定で扱います(実際の API 名はプロジェクト設定に依存しますが、汎用的な想定として実装します)。
setLanguage(langCode: string): 言語コードを指定して切り替える。getLanguage(): string: 現在の言語コードを取得する。
もしプロジェクトの TranslationServer API 名が異なる場合は、該当箇所のメソッド名だけを差し替えれば動くように、実装は 1 箇所にまとめています。
3. Inspector で設定可能なプロパティ設計
LocalizationMgr コンポーネントで用意するプロパティは次の通りです。
- initialLanguage (Enum)
- 型:
LanguageType(独自 enum:JA/EN) - 役割: シーン開始時(
start())に自動で設定する言語。 - 例:
JAを指定するとゲーム開始時に日本語 UI へ、ENなら英語 UI へ切り替え。
- 型:
- applyOnStart (boolean)
- 初期値:
true - 役割: シーン開始時に
initialLanguageを自動適用するかどうか。 falseにすると、手動でsetJapanese()/setEnglish()/toggleLanguage()を呼ぶまで言語を変更しない。
- 初期値:
- enableKeyToggle (boolean)
- 初期値:
false - 役割: エディタ再生中に特定キーで言語を切り替えるデバッグ機能を有効にするか。
- 初期値:
- toggleKey (string)
- 初期値:
'L' - 役割:
enableKeyToggleがtrueのとき、このキーを押すと日本語/英語をトグルする。 - 大文字・小文字を区別せずに判定する実装にします。
- 初期値:
- currentLanguage (readonly string / 表示用)
- Inspector 上で現在の言語コード(
ja/enなど)を確認するための表示用プロパティ。 - スクリプトから更新されるが、ユーザーが直接編集しても意味はない(説明を tooltip で明記)。
- Inspector 上で現在の言語コード(
また、エディタの「イベントから直接呼び出しやすい public メソッド」も用意します。
setJapanese(): 言語を日本語に切り替え。setEnglish(): 言語を英語に切り替え。toggleLanguage(): 現在の言語が日本語なら英語へ、英語なら日本語へ切り替え。
これにより、ボタンの ClickEvents から LocalizationMgr のメソッドを直接呼び出して、UI ボタンで言語切替を実装できます。
TypeScriptコードの実装
import { _decorator, Component, director, systemEvent, SystemEvent, EventKeyboard, KeyCode } from 'cc';
const { ccclass, property, tooltip } = _decorator;
/**
* 言語種別の列挙
* Inspector では JA / EN として選択できるようにする。
*/
enum LanguageType {
JA = 0,
EN = 1,
}
@ccclass('LocalizationMgr')
export class LocalizationMgr extends Component {
@property({
type: LanguageType,
tooltip: 'シーン開始時に適用する初期言語。\nJA: 日本語, EN: 英語',
})
public initialLanguage: LanguageType = LanguageType.JA;
@property({
tooltip: 'true の場合、start() のタイミングで initialLanguage を自動適用します。',
})
public applyOnStart: boolean = true;
@property({
tooltip: 'true にすると、再生中に特定キーを押すことで日本語/英語をトグル切り替えできます(デバッグ用)。',
})
public enableKeyToggle: boolean = false;
@property({
tooltip: '言語トグルに使用するキー(例: "L")。\n大文字・小文字は区別されません。',
})
public toggleKey: string = 'L';
@property({
tooltip: '現在の言語コードを表示します(例: "ja", "en")。\nスクリプトから自動更新されるため、手動で変更する必要はありません。',
readonly: true,
})
public currentLanguage: string = '';
/**
* TranslationServer への参照。
* 3.8 では director.root?.dataPoolManager.translationServer のような場所に存在することを想定。
* any 型で保持し、存在チェックとメソッド存在チェックを行う。
*/
private _translationServer: any | null = null;
/**
* キーボードトグル用のキャッシュキーコード。
*/
private _toggleKeyCode: KeyCode | null = null;
onLoad() {
// TranslationServer を探す
this._initTranslationServer();
// キートグル用キーコードを準備
this._initToggleKeyCode();
// キーボードイベント登録(必要な場合のみ)
if (this.enableKeyToggle) {
this._registerKeyboardEvent();
}
}
start() {
// シーン開始時に初期言語を適用
if (this.applyOnStart) {
if (this.initialLanguage === LanguageType.JA) {
this.setJapanese();
} else {
this.setEnglish();
}
} else {
// 現在の言語を TranslationServer から取得して表示用プロパティを更新
this._updateCurrentLanguageFromServer();
}
}
onEnable() {
// コンポーネントが有効化されたとき、キートグルが有効ならイベントを登録
if (this.enableKeyToggle) {
this._registerKeyboardEvent();
}
}
onDisable() {
// 無効化時にイベント解除
this._unregisterKeyboardEvent();
}
onDestroy() {
// 破棄時にも念のためイベント解除
this._unregisterKeyboardEvent();
}
/**
* 日本語に切り替える(Button の ClickEvents からも直接呼び出し可能)。
*/
public setJapanese() {
this._setLanguageCode('ja');
}
/**
* 英語に切り替える(Button の ClickEvents からも直接呼び出し可能)。
*/
public setEnglish() {
this._setLanguageCode('en');
}
/**
* 現在言語が ja なら en、そうでなければ ja に切り替える。
*/
public toggleLanguage() {
if (!this._translationServer) {
console.warn('[LocalizationMgr] TranslationServer が見つからないため、toggleLanguage は動作しません。');
return;
}
const current = this._getLanguageCodeFromServer();
const next = (current === 'ja') ? 'en' : 'ja';
this._setLanguageCode(next);
}
/**
* TranslationServer を初期化して取得する。
* 存在しない場合は error ログを出して _translationServer を null にする。
*/
private _initTranslationServer() {
const root: any = (director as any).root;
if (!root) {
console.error('[LocalizationMgr] director.root が見つかりません。TranslationServer にアクセスできません。');
this._translationServer = null;
return;
}
const dataPoolManager = root.dataPoolManager;
if (!dataPoolManager) {
console.error('[LocalizationMgr] dataPoolManager が見つかりません。TranslationServer にアクセスできません。');
this._translationServer = null;
return;
}
const translationServer = dataPoolManager.translationServer;
if (!translationServer) {
console.error('[LocalizationMgr] translationServer が見つかりません。プロジェクト設定を確認してください。');
this._translationServer = null;
return;
}
// 最低限 setLanguage が存在するかチェック(なければ API 名をプロジェクトに合わせて修正する必要がある)
if (typeof translationServer.setLanguage !== 'function' && typeof translationServer.setLang !== 'function') {
console.error('[LocalizationMgr] TranslationServer に setLanguage / setLang メソッドが見つかりません。プロジェクトの API 名を確認してください。');
this._translationServer = null;
return;
}
this._translationServer = translationServer;
this._updateCurrentLanguageFromServer();
console.log('[LocalizationMgr] TranslationServer を初期化しました。');
}
/**
* TranslationServer に言語コードを設定する共通処理。
* @param lang 設定したい言語コード(例: "ja", "en")
*/
private _setLanguageCode(lang: string) {
if (!this._translationServer) {
console.error('[LocalizationMgr] TranslationServer が見つからないため、言語を設定できません。');
return;
}
// TranslationServer の API 名が setLanguage か setLang かを動的に判定
if (typeof this._translationServer.setLanguage === 'function') {
this._translationServer.setLanguage(lang);
} else if (typeof this._translationServer.setLang === 'function') {
this._translationServer.setLang(lang);
} else {
console.error('[LocalizationMgr] TranslationServer に有効な言語設定メソッドが存在しません。setLanguage / setLang を確認してください。');
return;
}
this.currentLanguage = lang;
console.log(`[LocalizationMgr] 言語を "${lang}" に切り替えました。`);
}
/**
* TranslationServer から現在の言語コードを取得し、currentLanguage を更新する。
*/
private _updateCurrentLanguageFromServer() {
if (!this._translationServer) {
return;
}
const lang = this._getLanguageCodeFromServer();
if (lang) {
this.currentLanguage = lang;
}
}
/**
* TranslationServer から現在の言語コードを取得する。
* getLanguage / getLang のどちらかが存在する前提で動的に呼び出す。
*/
private _getLanguageCodeFromServer(): string {
if (!this._translationServer) {
return '';
}
let lang = '';
if (typeof this._translationServer.getLanguage === 'function') {
lang = this._translationServer.getLanguage();
} else if (typeof this._translationServer.getLang === 'function') {
lang = this._translationServer.getLang();
}
if (typeof lang !== 'string') {
lang = '';
}
return lang;
}
/**
* Inspector の toggleKey (文字列) から KeyCode を推定してキャッシュする。
* 未対応のキーの場合は null のままにして警告を出す。
*/
private _initToggleKeyCode() {
if (!this.toggleKey || this.toggleKey.length === 0) {
this._toggleKeyCode = null;
return;
}
const keyChar = this.toggleKey.toUpperCase();
switch (keyChar) {
case 'A': this._toggleKeyCode = KeyCode.KEY_A; break;
case 'B': this._toggleKeyCode = KeyCode.KEY_B; break;
case 'C': this._toggleKeyCode = KeyCode.KEY_C; break;
case 'D': this._toggleKeyCode = KeyCode.KEY_D; break;
case 'E': this._toggleKeyCode = KeyCode.KEY_E; break;
case 'F': this._toggleKeyCode = KeyCode.KEY_F; break;
case 'G': this._toggleKeyCode = KeyCode.KEY_G; break;
case 'H': this._toggleKeyCode = KeyCode.KEY_H; break;
case 'I': this._toggleKeyCode = KeyCode.KEY_I; break;
case 'J': this._toggleKeyCode = KeyCode.KEY_J; break;
case 'K': this._toggleKeyCode = KeyCode.KEY_K; break;
case 'L': this._toggleKeyCode = KeyCode.KEY_L; break;
case 'M': this._toggleKeyCode = KeyCode.KEY_M; break;
case 'N': this._toggleKeyCode = KeyCode.KEY_N; break;
case 'O': this._toggleKeyCode = KeyCode.KEY_O; break;
case 'P': this._toggleKeyCode = KeyCode.KEY_P; break;
case 'Q': this._toggleKeyCode = KeyCode.KEY_Q; break;
case 'R': this._toggleKeyCode = KeyCode.KEY_R; break;
case 'S': this._toggleKeyCode = KeyCode.KEY_S; break;
case 'T': this._toggleKeyCode = KeyCode.KEY_T; break;
case 'U': this._toggleKeyCode = KeyCode.KEY_U; break;
case 'V': this._toggleKeyCode = KeyCode.KEY_V; break;
case 'W': this._toggleKeyCode = KeyCode.KEY_W; break;
case 'X': this._toggleKeyCode = KeyCode.KEY_X; break;
case 'Y': this._toggleKeyCode = KeyCode.KEY_Y; break;
case 'Z': this._toggleKeyCode = KeyCode.KEY_Z; break;
default:
this._toggleKeyCode = null;
console.warn(`[LocalizationMgr] toggleKey "${this.toggleKey}" は現在の実装では未対応です。A〜Z のいずれかを指定してください。`);
break;
}
}
/**
* キーボードイベントを登録する。
*/
private _registerKeyboardEvent() {
if (!this._toggleKeyCode) {
return;
}
systemEvent.on(SystemEvent.EventType.KEY_UP, this._onKeyUp, this);
}
/**
* キーボードイベントを解除する。
*/
private _unregisterKeyboardEvent() {
systemEvent.off(SystemEvent.EventType.KEY_UP, this._onKeyUp, this);
}
/**
* キーアップイベントハンドラ。
* 指定キーが離されたときに toggleLanguage() を呼び出す。
*/
private _onKeyUp(event: EventKeyboard) {
if (!this.enableKeyToggle || !this._toggleKeyCode) {
return;
}
if (event.keyCode === this._toggleKeyCode) {
this.toggleLanguage();
}
}
}
コードの主要部分の解説
onLoad()_initTranslationServer()で TranslationServer を取得し、存在しない場合はerrorログを出して以降の処理を安全にスキップ。_initToggleKeyCode()で Inspector のtoggleKeyからKeyCodeを算出。enableKeyToggleがtrueの場合のみ、キーボードイベントを登録。
start()applyOnStartがtrueなら、initialLanguageをもとにsetJapanese()またはsetEnglish()を呼び出す。falseの場合は、TranslationServer から現在の言語を取得してcurrentLanguageに反映。
setJapanese()/setEnglish()/toggleLanguage()- すべて
_setLanguageCode()に集約して実際の切り替え処理を行う。 - ボタンイベントから直接呼び出せるよう
publicメソッドとして定義。
- すべて
_setLanguageCode()- TranslationServer の
setLanguage()またはsetLang()を動的に判定して呼び出す。 - 成功したら
currentLanguageを更新し、ログを出力。 - TranslationServer が取得できない場合や API が見つからない場合は
errorログのみで安全に終了。
- TranslationServer の
- キーボードトグル処理
_initToggleKeyCode()でtoggleKey(例: “L”)をKeyCode.KEY_Lに変換。enableKeyToggleがtrueかつ_toggleKeyCodeが有効な場合のみ、systemEventにKEY_UPイベントを登録。- 指定キーが離されたときに
toggleLanguage()を呼び出す。
使用手順と動作確認
1. スクリプトファイルの作成
- Assets パネルで右クリック → Create → TypeScript を選択。
- ファイル名を
LocalizationMgr.tsに変更。 - 生成されたスクリプトをダブルクリックして開き、本文をすべて削除して、上記の TypeScript コードを丸ごと貼り付けます。
- 保存します(Ctrl+S / Cmd+S)。
2. テスト用シーンノードの準備
- Hierarchy パネルで右クリック → Create → Empty Node を選択し、名前を
LocalizationRootなどに変更します。 - このノードは単なる「ローカライズ制御用の入れ物」なので、特別なコンポーネントは不要です。
3. LocalizationMgr コンポーネントのアタッチ
- Hierarchy で
LocalizationRootノードを選択。 - Inspector 下部の Add Component ボタンをクリック。
- Custom カテゴリから LocalizationMgr を選択してアタッチします。
4. Inspector プロパティの設定
LocalizationRoot を選択した状態で、Inspector に表示される LocalizationMgr のプロパティを確認・設定します。
- Initial Language(initialLanguage)
- 例: JA に設定すると、シーン開始時に日本語に切り替え。
- 例: EN に設定すると、シーン開始時に英語に切り替え。
- Apply On Start(applyOnStart)
- 通常は ON(true) のままで OK。
- シーン開始時に自動で言語を切り替えたくない場合のみ OFF にします。
- Enable Key Toggle(enableKeyToggle)
- デバッグ用途で、エディタ再生中にキーで言語を切り替えたい場合は ON。
- 本番ビルドでは OFF にしておくことを推奨します。
- Toggle Key(toggleKey)
- 例:
Lと入力すると、再生中にキーボードの L キー を離したタイミングで日本語/英語がトグル切り替えされます。 - A〜Z の英字のみ対応しています。
- 例:
- Current Language(currentLanguage)
- 現在の言語コード(
ja/en)が表示されます。 - スクリプトから自動更新されるため、ユーザーが手動で変更する必要はありません。
- 現在の言語コード(
5. 実行して TranslationServer が動作しているか確認
- エディタ上部の Preview(再生ボタン) を押してシーンを実行します。
- Console パネル(またはブラウザの DevTools コンソール)を開きます。
- 初期化時に以下のようなログが出ていれば、TranslationServer の取得に成功しています:
[LocalizationMgr] TranslationServer を初期化しました。[LocalizationMgr] 言語を "ja" に切り替えました。(または"en")
enableKeyToggle = trueにしている場合、L キー(デフォルト)を押して離すと、コンソールに[LocalizationMgr] 言語を "en" に切り替えました。[LocalizationMgr] 言語を "ja" に切り替えました。
のようなログが交互に表示されることを確認します。
6. UI ボタンから言語切り替えを行う
次に、ゲーム内 UI ボタンから言語を切り替える手順です。
- Hierarchy で Canvas 配下に Button を 2 つ作成します(例:
BtnJapanese,BtnEnglish)。 BtnJapaneseを選択し、Inspector の Button コンポーネント内の Click Events セクションを開きます。- + ボタンを押してイベントを追加し、対象ノードに
LocalizationRootをドラッグ&ドロップします。 - その右側のコンポーネント選択ドロップダウンから LocalizationMgr を選択。
- メソッド一覧から
LocalizationMgr.setJapaneseを選択します。 - 同様に
BtnEnglishに対しても ClickEvents を設定し、今度はLocalizationMgr.setEnglishを選びます。 - シーンを再生し、
BtnJapanese/BtnEnglishをクリックすることで、TranslationServer が日本語/英語に切り替わることを確認します。
ゲーム内のテキストが TranslationServer を参照するように設定されていれば、ボタンを押すだけで UI テキストが即座に切り替わるようになります。
まとめ
本記事では、Cocos Creator 3.8.7 + TypeScript で、
- TranslationServer を制御して日本語/英語を即座に切り替える汎用コンポーネント
LocalizationMgr
を、完全に独立したスクリプトとして実装しました。
本コンポーネントのポイントは以下の通りです。
- 他の GameManager やシングルトンに依存せず、任意のノードにアタッチするだけで動作する。
- Inspector から
- 初期言語(JA / EN)
- 自動適用の有無
- キー入力によるトグル切り替え(デバッグ用)
を柔軟に設定できる。
- UI ボタンの ClickEvents から
setJapanese()/setEnglish()/toggleLanguage()を直接呼び出せるため、シーン側の実装コストを最小限にできる。 - TranslationServer 取得や API 名は防御的にチェックしており、問題があれば
errorログで検出しやすい。
このコンポーネントをプロジェクトに組み込んでおけば、
- タイトル画面だけ英語固定にする
- オプション画面の「言語」メニューから即座に切り替える
- デバッグ時にショートカットキーで言語を切り替えて UI の崩れを確認する
といった場面で、LocalizationMgr を 1 つアタッチするだけで簡単に制御できます。
必要に応じて、対応言語を増やしたり、プラットフォームの言語設定から初期言語を自動判定する処理を追加するなど、プロジェクトに合わせて拡張してみてください。




