ゲームイベントシステム
Unityのための本格的なビジュアルイベントアーキテクチャ。混沌としたイベント管理を、保守性と検証性に優れたワークフローへと変革します。

「このシステムを開発したのは、自分自身のプロジェクトで『見えないスパゲッティコード』と戦うことに疲れたからです。インディー開発者として、ビジュアル面での明快さとコーディングパワーを両立し、しかもパフォーマンスを犠牲にしないツールが必要でした。TinyGiantsは、私が日々自分のゲーム開発で使用しているプロフェッショナルグレードのツールへの私のこだわりです。」 — [TinyGiants] 中国より
このシステムが存在する理由
従来のUnity開発では、イベントが見えないスパゲッティと化します:
- 隠された依存関係: 誰がリッスンしている?どこでトリガーされる?見つけ出すのは困難です。
- 実行時の破損: メソッド名を変更すると、10個のシーンオブジェクトが壊れます。
- クロスシーンの混乱: シーンがアンロードされるとイベントが消失し、メモリリークとNull参照があちこちに発生します。
- 可視性の欠如: 複雑なイベントチェーンは、あなたの頭の中(と古くなったコメント)にしか存在しません。
TinyGiants.GameEventSystemは、ビジュアルファースト、型安全なイベントアーキテクチャを提供します:
✅ アセットとしてのイベント - ScriptableObjectベース、GUID保護、リファクタリングに耐える設計
✅ ビジュアルフローグラフ - イベントチェーン、トリガー、条件を一つのウィンドウで可視化
✅ ゼロリフレクション実行 - Expression Treeコンパイルによる、C++並みのパフォーマンス
✅ デザイナーフレンドリー - ドラッグ&ドロップバインディング、シンプルなワークフローにコーディングは不要
✅ 本格的なツール群 - リアルタイムモニタリング、参照検索、コード生成の自動化
コアアーキテクチャ:動作の仕組み
GameEventSystem は、イベントロジックを集中管理しつつ、実行の分散化を維持するために設計された「管理-アセット-アクション」アーキテクチャに基づいています。

🏗️ 基盤:GameEventManager とデータベース
システムの中心となるのは、イベントデータベースを管理・維持する GameEventManager です。
- アセットとしてのイベント:すべてのイベントはデータベースアセット内に保存された
ScriptableObjectです。 - 集中管理:GameEventEditorWindow が主要なコマンドセンターとして機能します。ここから以下の専用ツールにアクセスできます:
- Creator:新しいイベントアセットを迅速に生成します。
- Behavior & Finder:イベントプロパティの設定や、シーンを横断した依存関係の特定を行います。
- FlowGraph:複雑で多段階のイベントシーケンスを視覚的に設計します。
- Monitor:リアルタイムのデバッグとパフォーマンス追跡を行います。
🔄 ハイブリッドワークフロー:ビジュアルとコード
このシステムは、技術的な実装とクリエイティブなデザインの間の溝をシームレスに埋めます。
- 直接的なコード統合:プログラマーはスクリプト内で単純な
.Raise()を呼び出すだけで、どこからでもイベントをトリガーできます。 - ビジュアルなインスペクター結合:デザイナーは直感的なドロップダウンメニューを使用して、インスペクター上で直接ロジックをイベントに結合できます。「マジックストリング」や手動のコンポーネント検索は不要です。
- リアルタイム監視:Monitor ウィンドウはイベントアクティビティをライブ表示し、再生モード中にデータフローと実行タイミングを確認するのに役立ちます。
💻 完全な API 互換性
デザイナー向けの強力なビジュアルインターフェースを提供していますが、本システムは API ファーストで設計されています。 ビジュアルエディターで利用可能なすべての機能は、Runtime API からもアクセス可能です。 グラフでイベントチェーンを構築する場合でも、C# コードで動的にリスナーを登録・解除する場合でも、システムは同等のパワーとパフォーマンスを提供します。
💡 なぜこのアーキテクチャなのか?
- デカップリング(疎結合):送信者と受信者は互いを知る必要はありません。イベントアセットさえ知っていれば動作します。
- 可視化:標準的なイベントによる「見えないスパゲッティコード」が、検索可能なビジュアルデータベースに置き換わります。
- 信頼性:イベントがアセットであるため、メソッド名の変更やファイルの移動を行っても参照が壊れることはありません。
アーキテクチャの特徴
🏗️ 基盤: ScriptableObjectドリブン
文字列ベースやシングルトンイベントシステムとは異なり、イベントは第一級のアセットです:
// イベントはアセットであり、マジックストリングではありません
[GameEventDropdown] public GameEvent onPlayerDeath;
[GameEventDropdown] public GameEvent<int> onScoreChanged;
void Die() {
onPlayerDeath.Raise(); // 型安全、アセット参照
}
利点:
- ✅ 完全な疎結合 - 送信者は受信者を知りません。一度発火すれば、多数に通知。
- ✅ クロスシーン永続性 - イベントはシーンのロード/アンロードに耐えます。
- ✅ GUID識別 - ファイル名を変更し、フォルダを再編成しても、参照は決して壊れません。
- ✅ マルチデータベースサポート - 大規模チーム向けのモジュラー構成。
📖 GUID保護の仕組み
各イベントは.metaファイルに保存された一意のGUIDを持ちます:
# PlayerDeath.asset.meta
guid: a7f3c21e9b4d8f6e2d1a9c8b7e6f5a4d
PlayerDeathをOnCharacterDiedに変更しても、UnityはGUIDを通じて参照を維持します。シーンリンクの破損はありません。
🕸️ ビジュアルフローオーケストレーション
イベントの関係性を理解するためにコードを探し回るのはもうやめましょう。フローエディターは、見えないロジックを保守可能なグラフへと変換します:
ユースケース
🎯 トリガー(ファンアウト)

⛓️ チェーン(シーケンシャル)

🔀 ハイブリッドフロー
並列+順次ロジックのミックス

- グループ整理 - 大規模フロー向けのカラーコード付きグループ
- リアルタイム検証 - 接続タイプチェック(緑=有効、赤=エラー)
- アンドゥ/リドゥサポート - 完全な履歴システム(Ctrl+Z/Y)
- 実行時デバッグ - プレイモード中にアクティブノードがハイライト
⚡ 型安全、ゼロリフレクションパフォーマンス
Unityのジェネリックシリアライゼーションは設計上壊れています。私はそれを修正しました。
問題点
// ❌ Unityはこれをシリアライズできません
[SerializeField] private GameEvent<PlayerData> onPlayerDataChanged;
本システムの解決策
// ✅ 自動生成される具象クラス
[GameEventDropdown] public PlayerDataGameEvent onPlayerDataChanged;
// 生成コード(自動):
[Serializable]
public class PlayerDataGameEvent : GameEvent<PlayerData> { }
パフォーマンス上の利点:
- 🚀 Expression Treeコンパイル - 条件は起動時にデリゲートへコンパイル(実行時パースなし)
- 🚀 リフレクションコストゼロ -
Invoke()ではなく、直接メソッド呼び出し - 🚀 ネイティブインスペクターサポート - 完全な
UnityEvent<T>互換性
⚙️ コード生成ワークフロー
- 型を選択 - Creatorウィンドウでカスタム型を選択
- 生成 - 「Generate」をクリックして具象クラスを作成
- コンパイル - Unityが新しいコードを自動コンパイル
- 作成 - これで、カスタム型のイベントを作成可能に
所要時間: 約10秒。効果: 生涯の型安全性。
機能マトリックス
⚓ コアアーキテクチャ
| 機能 | 説明 |
|---|---|
| アセットベースイベント | GUID識別を持つScriptableObjectアーキテクチャ—参照はリネームやファイル移動に耐えます。 |
| 包括的なジェネリクス | GaneEvent<Void>、GameEvent<T>、ソース認識型GameEvent<TSender, TArgs>のネイティブサポート。 |
| マルチデータベースシステム | 動的ロードとヘルスチェックを備えた、複数データベースをサポートするモジュラー構成。 |
| カテゴリーシステム | 大規模イベントライブラリ内での効率的なファジー検索フィルタリングのための文字列ベースの分類。 |
| 自動静的リセット | エディタープレイモードでの静的キャッシュの自動クリアによるデータ汚染の防止。 |
🧠 高度なロジック&フロー
| 機能 | 説明 |
|---|---|
| Expression Tree | ゼロリフレクションのロジック評価;条件は実行時に高性能デリゲートへコンパイルされます。 |
| ビジュアルロジックビルダー | コード不要で複雑なネストされたAND/ORロジックと動的プロパティ比較を構築。 |
| ハイブリッド実行 | 並列ファンアウトトリガーと順次ブロッキングチェーンを一つのグラフ内でシームレスにミックス。 |
| 引数トランスフォーマー | フローノード間で特定のオブジェクトプロパティを引数として動的に抽出・渡す。 |
| きめ細かいフロー制御 | ノード単位の遅延、非同期/コルーチン待機、ループカウント、条件付き実行ゲート。 |
🎧 リスニング&バインディング
| 機能 | 説明 |
|---|---|
| ビジュアルバインディング | インスペクターでのドラッグ&ドロップUnityEvent配線、ビジュアルステータスマーカーと型安全性付き。 |
| 優先度リスナー | 整数ベースのソートにより、重要なシステムが標準UI/Audioリスナーより先に反応することを保証。 |
| 条件付きリスナー | 組み込みのPredicateサポート—コールバックは特定の論理条件が満たされた場合にのみ発火。 |
| 永続リスナー | シーン遷移中もアクティブを維持するクロスシーンリスナーのネイティブサポート。 |
| 動的実行時API | リスナーの登録/登録解除およびタスクハンドル管理のための完全なプログラマティック制御。 |
📊 ツール&デバッグ
| 機能 | 説明 |
|---|---|
| ダッシュボード&ウィザード | バッチ操作のためのモダンUIと、迅速なイベント作成のためのファジーマッチングウィザード。 |
| コード自動化 | 自動コンパイルパイプライン統合を備えた三モードCodeGen(Basic/Custom/Sender)。 |
| 参照ファインダー | 特定のイベントアセットを参照しているコンポーネントを正確に特定するシーン全体スキャナー。 |
| 実行時モニター | 実行時間(平均/最小/最大)、リスナー数、GCアロケーションのリアルタイムプロファイリング。 |
| 自動化ツリー | 複雑なロジックフローをデバッグするための、アクティブなトリガーとチェーン階層のリアルタイムビジュアライザー。 |
パフォーマンス特性
本番ビルドからの実測値:
| シナリオ | パフォーマンス | 備考 |
|---|---|---|
| イベント発火(リスナー0) | ~0.001ms | 実質的にコストなし |
| イベント発火(リスナー10) | ~0.02ms | GCアロケーションなし |
| 条件評価 | ~0.003ms | Expression Treeコンパイル |
| フローノード実行 | ~0.05ms | コルーチンオーバーヘッド含む |
| モニターウィンドウ(イベント100) | ~0.3ms | エディターのみ、実行時コストなし |
シーン全体で500以上のイベントと10,000以上のリスナーを持つ出荷タイトルでテスト済み。パフォーマンス低下ゼロ。
🗺️ ナビゲーションロードマップ
このマップは、システムドキュメント全体の概要を提供します。以下のテーブルを使用して、必要な特定の機能やチュートリアルに素早くジャンプできます。
- 🚀 最速スタート: Example: Quick Startに直接ジャンプ。
- 🎨 ビジュアル学習者: ビジュアルワークフローとフローオーケストレーションテーブルに集中。
- 💻 プログラマー向け詳細: 実行時APIに直接進む。
🏁 1. イントロダクション
イベントアズアセットアーキテクチャの基本セットアップと核となる哲学。
| ページ | 説明 |
|---|---|
| プロジェクト構造 | ディレクトリレイアウト、フォルダ保護、モジュラー構成の理解。 |
| インストール | プラグインの初期化と自動静的リセットパイプラインのセットアップ。 |
💎 2. ビジュアルワークフロー
見えないコードを有形のビジュアルダッシュボードへと変換するために設計された管理ツール。
| ページ | 説明 |
|---|---|
| システムダッシュボード | アセットベースワークフローとGUID識別システムの概要 |
| データベース&フローグラフ | マルチデータベースおよびマルチフローグラフのセットアップとデータベースヘルスメンテナンス |
| ゲームイベント編集 | バッチ編集、検索、カテゴリー分類のためのダッシュボードの使用 |
| ゲームイベント作成 | ファジー検索バッチウィザードを使用したイベントアセットの迅速な生成 |
| ゲームイベント構成 | ビジュアルステータスマーカーと型安全性を備えたインスペクターバインディングのマスター |
| ゲームイベント発火 | イベントの呼び出し方法と組み込みGameEventDropdown属性を使用したインスペクターの強化方法を学ぶ |
| ゲームイベント検索 | コンポーネントレベルのイベント依存関係を見つけるためのシーンスキャン。 |
| ビジュアル条件ツリー | 条件ツリー構成を通じてイベントアクションのロジック実行を制御する方法を学ぶ |
🕸️ 3. フローオーケストレーション
ノードを使用した複雑なマルチステップロジックシーケンスの可視化と構築。
| ページ | 説明 |
|---|---|
| ノードエディター | GraphViewキャンバス、グループ、スナップショットベースのアンドゥ/リドゥの管理 |
| ノードコネクター | ハイブリッド実行モードのルールとリアルタイム接続検証 |
| ノードビヘイビア | ノードレベルの遅延、ループ、引数変換ロジックの構成 |
| 高度なロジックパターン | ノーコードのネストされたロジックグループと条件付き実行ゲートの構築 |
💻 4. スクリプティング&API
高性能C#統合とライフサイクル管理のための開発者ガイド。
| ページ | 説明 |
|---|---|
| 発火&スケジューリング | プログラマティック発火、遅延実行、タスクハンドル管理 |
| リスニング戦略 | 優先度付き、永続、ソース認識(Sender)リスナーの実装 |
| プログラマティックフロー | ゼロリフレクションロジックフィルタリングのためのExpression Treeベース述語の使用 |
| ベストプラクティス | クリーンな疎結合とデータ汚染防止のためのアーキテクチャのヒント |
| APIリファレンス | 全コアクラスと属性の詳細な技術ドキュメント |
🛠️ 5. ツール&サポート
プロフェッショナルな本番環境のための自動化およびモニタリングユーティリティ。
| ページ | 説明 |
|---|---|
| CodeGen&クリーンアップ | 三モードジェネレーターとコンパイルパイプライン自動化の使用 |
| 実行時モニター | リアルタイムパフォーマンスプロファイリング、詳細ログ、警告システム |
| コミュニティ&サポート | アップデートへのアクセス、バグ報告、技術サポートの取得 |
📚 6. 例
基本から高度なAPI使用まで、すべてのシナリオをカバーする実用的ですぐに使えるシーン。
| ID | 例ページ | 主要な学習ポイント |
|---|---|---|
| 00 | クイックスタート | イベントの作成、発火、バインディングのための最小限のワークフロー |
| 01 | Voidイベント | 「レベル開始」のようなグローバルトリガーのためのパラメータなしシグナルの使用 |
| 02 | 基本型イベント | イベントを通じてプリミティブデータ(int、float、string)を渡す |
| 03 | カスタム型イベント | シリアライズされたカスタムデータクラスと構造体のためのCodeGenの活用 |
| 04 | カスタムSenderイベント | どのエンティティがシグナルを発火したかを識別するソース認識イベントの使用 |
| 05 | 優先度イベント | 複数のリスナーの実行順序を正確に制御 |
| 06 | 条件付きイベント | 条件が満たされた場合にのみコールバックを実行するための述語の使用 |
| 07 | 遅延イベント | タイミングロジックの管理とキャンセルのためのタスクハンドルの使用 |
| 08 | 繰り返しイベント | 繰り返しパルスシグナルと自動ロジックループの作成 |
| 09 | 永続イベント | シーン遷移中のイベント処理(DontDestroyOnLoad) |
| 10 | トリガーイベント | UnityのPhysicsシステムとGame Eventアセットのブリッジング |
| 11 | チェーンイベント | フローオーケストレーショングラフを使用したビジュアルシーケンシャルロジックの構築 |
| 12 | マルチデータベース | モジュラープロジェクト構成のための異なるアセットへのイベント分離 |
| 13 | 実行時API | C#スクリプトを介してリスナーを動的に登録/登録解除 |
| 14 | 実行時モニター | 実行タイミングとGCアロケーションをデバッグするためのプロファイリングツールの使用 |
実践的な開始には、まずExample 00(クイックスタート)に従い、その後ビジュアルワークフローセクションを探索して、エディターツールがどのように開発を効率化できるかを確認することをお勧めします。