Unity

【Unity】Game Creator 2 応用機能(Audio/Signals/Save&Load/Tween)完全解説

【Unity】Game Creator 2 応用機能(Audio/Signals/Save&Load/Tween)完全解説

当サイトを閲覧いただきありがとうございます。

本記事では、Game Creator 2のコアに含まれる「応用機能群(Advanced)」について詳しく解説します。

これらは Characters・Cameras・Visual Scripting・Variables といった大きな柱の下で共有される横断的な仕組みであり、プログラマ向けの拡張APIも多く含まれています。Audio管理からSave&Load、Tweenまで、ゲーム開発で頻繁に使う機能が揃っています。

公式ドキュメント:Game Creator 2 Documentation


概要

公式ドキュメントの Advanced 章は、Unityと GC2 の基礎が分かったユーザー・プログラマ向けのツール箱です。本章では以下を扱います。

  • Audio:5チャンネル音声管理(Ambient/Music/SFX/UI/Speech)
  • Signals:IDベースのブロードキャストで疎結合の通信
  • Data Structures:シリアライズ可能な辞書・ツリー・リングバッファ・Spatial Hash・State Machine など
  • Variables API:スクリプトからローカル/グローバル変数を操作
  • Properties:値供給元をドロップダウンで切替できるフィールド抽象
  • Save & LoadIGameSave インターフェースと SaveLoadManagerRemember コンポーネント
  • Tweening:値の補間アニメーション
  • Custom Installs:モジュール開発者向けのサンプル/テンプレート配布の仕組み
  • Domain Reload:Unityの再読込スキップ対応

Audio ― 5チャンネル音声システム

GC2 の Audio Manager が AudioSource の生成・破棄を自動で最適化します。5つのチャンネルがあり、それぞれ独立した音量スライダーを持ちます。

チャンネル一覧

チャンネル用途主な命令
Ambient環境音(ループ・diegetic/non-diegetic どちらも可)Play Ambient / Stop Ambient / Fade All Ambient
MusicBGM(non-diegetic、v2.6.22以降追加)Play Music / Stop Music / Fade All Music
Sound Effects (SFX)単発の効果音。デフォルトで空間位置を持つdiegetic音Play Sound Effect / Stop Sound Effect
UIUI操作音(ホバー、クリック、クラフト完了など。non-diegetic)Play UI Sound
Speechキャラクターに紐付いた発話(1キャラ1クリップ同時再生)Play Speech / Stop Speech On Game Object

Sound Variation

同じSFXが繰り返し鳴って不自然にならないよう、ピッチと再生速度を自動的にわずかに揺らす機構が組み込まれています。機関銃のような連射SEでも同じクリップで自然に鳴らせます。

Snapshot

Change Snapshot で AudioMixer のスナップショットを切り替えられます。屋内/屋外のリバーブ変更や、特定シーンでのローパスフィルタ適用などに使います。

AudioSource 直接操作

個別の AudioSource の Pitch と Volume を命令で変更することもできます。

  • Audio Source Pitch
  • Audio Source Volume
  • Audio Mixer Parameter

Signals ― シグナルによる疎結合通信

GC2 には標準で Trigger/Action/Conditions の連携手段が豊富ですが、それでもカスタムイベントをIDで発火したいケース(例:boss-defeatedcinematic-end)があります。そのための最小機構が Signal です。

  • 送信:Instruction Emit Signal(Visual Scripting)/内部的には Raise Signal
  • 受信:Trigger の Event を On Receive Signal にして識別子を指定
  • 送信側と受信側が互いを知らないため、プレハブ化や再利用に強い

Favorite(お気に入り登録)

シグナル名の打ち間違い防止のため、名前をお気に入り登録 できます(右端のドロップダウンから選ぶ)。登録/解除はスターアイコンで切替です。


Properties

フィールドの値を「定数/変数/プレイヤー位置/…」のように動的に選ぶドロップダウンを提供する共通の仕組みです。

詳細とC#からの使い方は Variables の記事の Properties 節を参照してください。


Data Structures(ADS:応用データ構造)

GC2 が提供するシリアライズ可能かつ拡張しやすい汎用データ構造群です。すべてC#から利用します。

Unique ID

public class MyComponent : MonoBehaviour
{
    public UniqueID myID = new UniqueID();
}
  • System.Guid は非シリアライズですが、UniqueID はシリアライズ可能で、インスペクタ上で再生成ボタン付きのカスタムUIが出ます
  • 比較は Hash のほうが高速:int hash = this.myID.Get.Hash;
  • 永続化用に文字列を取りたい場合のみ string id = this.myID.Get.String;

Singleton<T>

public class MyClass : Singleton<MyClass>
{
    protected override void OnCreate() { base.OnCreate(); /* setup */ }
    protected override void OnDestroy() { base.OnDestroy(); /* teardown */ }
    protected override bool SurviveSceneLoads => false; // シーン切替で破棄したい場合
}
// 利用: MyClass.Instance
  • MonoBehaviour 前提(Singleton<T> が内部的に継承)
  • Instance は初回参照時に自動生成。既定ではシーンを跨いで生存します
  • SurviveSceneLoads で生存ポリシーを切替可能

Serializable Dictionary

public class MyDictionary : TSerializableDictionary<string, GameObject> {}
// 使い方は System.Collections.Dictionary と同じ

Serializable HashSet

public class MyHashSet : TSerializableHash<string> {}

Serializable LinkedList

public class MyLinkedList : TSerializableLinkList<GameObject> {}
// Add / AddFirst / AddLast / First() など LinkedList 同様

Serializable Matrix 2D

public class MyMatrix : TSerializableMatrix2D<GameObject> {}

MyMatrix matrix = new MyMatrix(10, 5);
matrix[2, 3] = gameObject;

Tree<T>

  • 非循環の親子依存関係を表す汎用ツリー
  • 自分自身がノード兼ツリーtree.Parenttree.Children(Idキーの辞書)
  • foreach で子ノード列挙、AddChild(value) で追加

Ring<T>(リングバッファ)

Ring<string> myRing = new Ring<string>("1", "2", "3", "4", "5");
myRing.Index = 0;
for (int i = 0; i < 100; i++) Debug.Log(myRing.Next()); // 20周する

myRing.Update(Debug.Log); // 各要素に関数適用

State Machine(汎用ステートマシン)

public class MyState1 : StateMachine.State
{
    protected override void WhenEnter(StateMachine m) {}
    protected override void WhenExit(StateMachine m) {}
    protected override void WhenUpdate(StateMachine m) {}
}

public class MyStateMachine : StateMachine
{
    public MyStateMachine(State state) : base(state) {}
}

var m = new MyStateMachine(new MyState1());
m.Change(new MyState2());
  • State 単位で WhenEnter / WhenExit / WhenUpdate をオーバーライド
  • EventOnEnter / EventOnExit / EventOnBeforeUpdate などイベントも公開
  • StateMachine の EventStateEnter / EventStateExit で遷移通知
  • Update は開発者が自分で呼ぶ必要があります(MonoBehaviourの Update から)
  • コンストラクタには初期 State を渡す必須

Spatial Hash

非物理ベースの高速な空間クエリです。O(log n) で半径検索ができます。

// ドメイン(静的クラス)
public static class MySpatialHash
{
    public static SpatialHash Value { get; private set; } = new SpatialHash();

    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
    private static void OnSubsystemsInit() => Value = new SpatialHash();
}

// 対象に ISpatialHash を実装
public class MyComponent : MonoBehaviour, ISpatialHash
{
    void OnEnable()  => MySpatialHash.Value.Insert(this);
    void OnDisable() => MySpatialHash.Value.Remove(this);
    void Update()    => MySpatialHash.Value.Update(this);

    Vector3 ISpatialHash.Position   => this.transform.position;
    int     ISpatialHash.UniqueCode => this.gameObject.GetInstanceID();
}

// クエリ
var list = MySpatialHash.Value.Query(new Vector3(0,0,0), 10f);
  • 位置が変わっていないフレームは Update を呼ばないと最適化になります
  • 1フレームで多数のクエリを叩くケースで真価を発揮します

Variables API

変数のランタイム値をスクリプトから読み書きするAPIです。詳細は Variables の記事の「Variables API」節を参照してください。


Save & Load(保存・読込)

柔軟なセーブ/ロードシステムです。デフォルトは Unity の PlayerPrefs を使いますが、保存先も暗号化も自作可能です。

保存先(Storage Location)

  • デフォルト:PlayerPrefs
  • ドロップダウンから切替可能。カスタムストレージ(自前DB/クラウド)に差し替えられます

暗号化(Encryption)

種類説明
None暗号化なし(既定)
XORパスフレーズとのXORによる簡易難読化
Caesar各文字を指定数シフト
カスタム自作クラスで自由に実装可能(後述)

保存可能な型

  • プリミティブ(int/bool/string/Vector/Quaternion)
  • [System.Serializable] 付きのマネージドクラス/構造体
  • UnityEngine.Object を継承するもの(GameObject/Transform/MonoBehaviour等)は保存不可

Slot(セーブスロット)

  • 1〜999 の整数で識別
  • 0番は共有設定用に予約(全スロットまたぎで共有したい設定値)

保存・読込・削除(API)

// 保存(Task を返す。PlayerPrefs はメインスレッドブロッキング)
_ = SaveLoadManager.Instance.Save(1);
// または async 関数で await
await SaveLoadManager.Instance.Save(1);

// 読込(現シーンを unload し、保存時のシーンを再ロード)
_ = SaveLoadManager.Instance.Load(1);

// 削除
_ = SaveLoadManager.Instance.Delete(1);

イベント(6種)

SaveLoadManager.Instance.EventBeforeSave   += slot => {};
SaveLoadManager.Instance.EventAfterSave    += slot => {};
SaveLoadManager.Instance.EventBeforeLoad   += slot => {};
SaveLoadManager.Instance.EventAfterLoad    += slot => {};
SaveLoadManager.Instance.EventBeforeDelete += slot => {};
SaveLoadManager.Instance.EventAfterDelete  += slot => {};

必ず OnDestroy 等で購読解除してください。

カスタムデータ ― IGameSave インターフェース

任意のコンポーネントに「保存可能」の印をつける仕組みです。

プロパティ/メソッド意味
string SaveIDこのデータを一意に識別するID
bool IsShared全セーブスロットで共有する値か
Type SaveType保存対象の型
object SaveData保存するインスタンス
LoadMode LoadModeLazy(通常90%)/Greedy(クロスシーン生存オブジェクト用)
void OnLoad(object value)ロード時に呼ばれる。valueを適切な型にキャストして復元

例として、開閉済みの宝箱を保存する実装です。

public class MyChest : MonoBehaviour, IGameSave
{
    public bool hasBeenOpened = false;

    void OnEnable()  => _ = SaveLoadManager.Subscribe(this);
    void OnDisable() => _ = SaveLoadManager.Unsubscribe(this);

    public string   SaveID   => "my-chest";
    public bool     IsShared => false;
    public Type     SaveType => typeof(bool);
    public object   SaveData => this.hasBeenOpened;
    public LoadMode LoadMode => LoadMode.Lazy;

    public void OnLoad(object value) => this.hasBeenOpened = (bool)value;
}

LoadMode(Lazy vs Greedy)

  • Lazy:対象オブジェクトが生成されたときに復元。大半はこれで問題ありません
  • GreedyDontDestroyOnLoad で生存するオブジェクト/シングルトン向け。ロードイベント即時で復元されます

カスタムストレージ(TDataStorage)

[Title("My Online Database")]
[Category("My Online Database")]
[Image(typeof(IconDiskSolid), ColorTheme.Type.TextLight)]
[Description("Stores the data in a custom database location")]
[Serializable]
public class MyOnlineDatabase : TDataStorage
{
    public override Task DeleteAll() { /* ... */ }
    public override Task DeleteKey(string key) { /* ... */ }
    public override Task<bool> HasKey(string key) { /* ... */ }
    public override Task<object> Get(string key, Type type) { /* ... */ }
    public override Task Set(string key, object value) { /* ... */ }
    public override Task Commit() { /* ... */ }
}
  • 命名規約は Storage<名前> 推奨
  • Commit は大量書込み後の一括コミット用

カスタム暗号化(TDataEncryption)

[Title("My Custom Encryption")]
[Serializable]
public class EncryptionMyCustom : TDataEncryption
{
    [SerializeField] private string privateKey;
    [SerializeField] private int salt;

    public override string Encrypt(string input) { /* ... */ }
    public override string Decrypt(string input) { /* ... */ }
}
  • [SerializeField] のフィールドはそのまま Settings 画面に現れます

Remember コンポーネント

「何を保存するか」を GameObject 単位で細かく選ぶためのコンポーネントです。既定で位置・回転・スケールを保存します。

Memory の追加

Add Memory ボタンで種類を選んで追加します。1コンポーネントに複数の Memory を持たせることができます。

カスタム Memory / Token

[Serializable]
public class MemoryName : Memory
{
    public override string Title => "Name of Game Object";
    public override Token GetToken(GameObject target) => new TokenName(target);

    public override void OnRemember(GameObject target, Token token)
    {
        if (token is TokenName tokenName) target.name = tokenName.text;
    }
}

[Serializable]
public class TokenName : Token
{
    public string text;
    public TokenName(GameObject target) : base() => this.text = target.name;
}
  • Memory クラスには [Title] [Category] [Image] [Description] 等のデコレーターが使えます

Tweening(補間アニメーション)

開始値→終了値を指定時間で補間する軽量APIです。ドアを2m上に開く、UIアルファをフェードする、色を徐々に変える、といった処理に便利です。

基本使用

Vector3 start = door.position;
Vector3 end   = door.position + Vector3.up * 2;
float duration = 5f;

ITweenInput tween = new TweenInput<Vector3>(
    start,
    end,
    duration,
    (a, b, t) => door.position = Vector3.Lerp(a, b, t),   // updateCall
    Tween.GetHash(typeof(Transform), "transform"),        // hash
    Easing.Type.QuadInOut                                 // easing
);

Tween.To(door.gameObject, tween);

パラメータ

フィールド意味
start / end開始・終了値。Vector3 以外にも floatColorQuaternion 等何でも可
duration補間にかかる秒数
updateCall毎フレーム呼ばれる関数。(start, end, ratio) を受け取り補間結果を反映
hashこのTweenの識別子。同じhashで別のTweenが始まると前者は自動キャンセル
easingイージング関数(指定無しはリニア)

Custom Installs(サンプル配布)

モジュール開発者が「自分のモジュール用のexample/template」Install... ウィンドウから配れるようにする仕組みです。

2つのフォルダ

  • Installer:配布元。Installer設定アセット+ Package.unitypackage
  • Installation Location:インストール先。固定で Assets/Plugins/Game Creator/Installs/<モジュール名>.<例名>@<版>/

Installer アセット

  • 作成:Project 右クリック → Create > Game Creator > Developer > Installer
  • 命名規約:<モジュール名>.<例名>
  • 主な設定:
    • Name / Module:カテゴリに影響
    • Description / Author:情報表示用
    • Version:セマンティックバージョン(更新時は必ず上げる)
    • Complexity:難易度の情報表示
    • Dependencies:他の例(module+example ID)を依存指定可能

依存関係

Install ウィンドウは依存先を自動で解決・インストールします。依存先が見つからなければエラーを出して中断します。


Domain Reload の扱い

GC2 は Unity の Domain Reload スキップ に対応しています。プレイモード切替時のリロード時間を短縮したい場合は以下のように設定します。

  1. Edit > Project Settings > Editor > Enter Play Mode Settings を開く
  2. Enter Play Mode Options を ON
  3. Reload Domain を OFF

にしても GC2 のシングルトン類が壊れないよう設計されています(公式ガイド推奨の設定)。


Visual Scripting リファレンス

Advanced に関連する Visual Scripting ノードをまとめます。

Instructions(Storage/Audio/Visual Scripting)

カテゴリ命令概要
StorageSave Game指定スロットに保存
Load Game指定スロットをロード
Load Latest Game最新セーブをロード
Delete Gameスロットを削除
Reset Game現在のランタイム状態をリセット
AudioPlay Ambient / Music / Sound Effect / Speech / UI Sound各チャンネルで再生
Stop Ambient / Music / Sound Effect / Speech On Game Object停止
Fade All Ambient / Fade All Music全アンビエント・BGMのフェード
Change Master / Ambient / Music / Sound Effects / Speech / UI Volumeチャンネル音量の時間変化付き変更
Change SnapshotAudioMixer スナップショット切替
Audio Source Pitch / Volume個別AudioSourceの調整
Audio Mixer ParameterAudioMixerの公開パラメータ変更
Visual ScriptingEmit Signalシグナル発火
Broadcast Message対象GameObjectにメッセージ送信(Upwards/Downwards)
Invoke Method任意コンポーネントのメソッドを呼ぶ
Run Actions / Conditions / Trigger他コンポーネントを実行(Wait Until Complete あり)
Stop Actions / Conditions / Trigger実行中のものを停止
Restart Instructions自Actionsを最初から再実行
Check Conditions途中条件失敗で以降を早期終了(AND/OR指定可)
Activate Hotspotsタイプ指定でHotspotの有効化/無効化

Conditions(Audio/Storage/Visual Scripting)

カテゴリ条件判定
AudioIs Ambient / Music / Sound Effect / Speech / Speech Target / UI Playingそれぞれが再生中か
StorageHas Save任意スロットにセーブがあるか
Has Save At Slot指定スロットにセーブがあるか
Visual ScriptingConditions As AndネストしたConditionsをAND評価
Run Conditions As OrネストしたConditionsをOR評価

Events(Audio/Storage/Logic)

カテゴリイベント発火タイミング
AudioOn Change Master / Ambient / Music / Sound Effects / Speech / UI Volume音量変化時
StorageOn Save / On Load / On Delete保存/読込/削除が起きたとき
LogicOn Hotspot Activate / Deactivate対応するHotspotの状態変化時
On Receive Signal指定IDのシグナル受信時

実践的な使い方 ― やりたいこと別の構成ガイド

BGMの状況別切替

  • 戦闘開始時:Fade All Music で現BGMをフェードアウト → Play Music で戦闘BGM
  • 戦闘終了時:逆手順。Change Snapshot と併用するとフィルタも切り替えられます

非同期セーブとトースト通知

public async void OnSaveClick()
{
    uiToast.Show("Saving...");
    await SaveLoadManager.Instance.Save(1);
    uiToast.Show("Saved!");
}

PlayerPrefs を使う限りはブロッキングなので事実上同期ですが、オンラインDBに切替えてもコードを変えずに済むのがポイントです。

任意のスクリプトをセーブ対象に

  • IGameSave を実装して OnEnableSubscribeOnDisableUnsubscribe
  • IDを一意な文字列にしておかないと衝突します

Signal の使い所

  • UI更新score-changed を Variable 変更 Trigger の中で Emit Signal → 複数のHUD/画面が購読
  • チュートリアル進行:チュートリアル側でしか知らない tutorial-step-3-ok シグナルで次段階へ

Tween で UI フェード

CanvasGroup group = ...;
float start = 0f, end = 1f, dur = 0.5f;

Tween.To(group.gameObject, new TweenInput<float>(
    start, end, dur,
    (a, b, t) => group.alpha = Mathf.Lerp(a, b, t),
    Tween.GetHash(typeof(CanvasGroup), "alpha"),
    Easing.Type.QuadInOut
));

同じ hash で別の Tween を始めれば前者は自動キャンセルされるため、衝突しません。

Spatial Hash + Perception の補完

Perception モジュールの Sight/Hearing が多数エージェント登場で重くなる場合、Spatial Hash で大雑把な近接フィルタをかけてから Perception の精査を走らせると軽くなります。

Singleton で Game Director を用意

public class GameDirector : Singleton<GameDirector>
{
    public int stageIndex;
    protected override bool SurviveSceneLoads => true;
}
// 利用: GameDirector.Instance.stageIndex = 3;

公式リンク


まとめ

本記事では、Game Creator 2 の応用機能(Advanced)について解説しました。如何だったでしょうか。

5チャンネルAudioでの音声管理、Signalによる疎結合通信、豊富なData Structures、柔軟なSave&Loadシステム、Tweenによる補間アニメーションなど、ゲーム開発の様々な場面で活躍する横断的な機能が揃っています。

特にSave&Loadは IGameSave インターフェースを実装するだけで任意のデータを保存対象にでき、ストレージや暗号化もカスタマイズ可能という柔軟な設計になっています。

全記事一覧 ― Game Creator 2 完全ガイド シリーズ総合案内senkohome.com/gamecreator2-series-index/

それでは次の記事も閲覧いただけると幸いです。