ゲームイベントの発火
イベントを作成し構成した後、最後のステップはゲームロジックでそれらをトリガーすることです。このページでは、ゲームイベントがどのように機能するか、スクリプトでそれらを発火する方法を示します。
- ✅ イベントを作成 → Game Event Creator
- ✅ アクションを構成 → Game Event Behavior
- ✅ イベントを発火 ← 現在地
🎯 ゲームイベントの仕組み
ゲームイベントはイベント発火とアクション実行を分離します:
従来のアプローチ:
// ❌ 密結合 - ドアのロジックがサウンド、アニメーションなどを知っている
public class Door : MonoBehaviour
{
public AudioSource audioSource;
public Animator animator;
public UIManager uiManager;
public void Open()
{
audioSource.Play();
animator.SetTrigger("Open");
uiManager.ShowNotification("Door opened");
// ロジックが複数の依存関係に分散
}
}
ゲームイベントアプローチ:
// ✅ 疎結合 - ドアは「何かが起こった」ことだけを知る
public class Door : MonoBehaviour
{
[GameEventDropdown]
public GameEvent onDoorOpened;
public void Open()
{
onDoorOpened.Raise(); // アクションはインスペクターで構成
}
}
主な違い: アクション(サウンド、アニメーション、UI)は、スクリプトにハードコードされるのではなく、Event Behaviorで視覚的に構成されます。
📝 基本的な使用法: イベントの発火
ステップ1: スクリプトでイベントを参照
using TinyGiants.GameEventSystem.Runtime;
using UnityEngine;
public class DoorController : MonoBehaviour
{
[GameEventDropdown] // スマートインスペクターピッカー
public GameEvent onDoorOpened;
[GameEventDropdown]
public GameEvent onDoorClosed;
public void OpenDoor()
{
// ドアのロジックをここに
onDoorOpened.Raise(); // イベントをトリガー
}
public void CloseDoor()
{
// ドアのロジックをここに
onDoorClosed.Raise();
}
}
ステップ2: インスペクターでイベントを割り当て
[GameEventDropdown]属性は型安全な検索可能ドロップダウンを提供します:

機能:
- 🔍 ファジー検索: 入力して名前でイベントをフィルタリング
- 📁 カテゴリ分け: データベースとカテゴリ別にグループ化されたイベント
- 🔒 型安全性: 互換性のあるイベント型のみを表示
- ⚡ クイックアクセス: 手動でアセットをドラッグする必要なし
代替: [GameEventDropdown]なし
標準のpublicフィールドを使用することもできます:
public GameEvent onDoorOpened; // 標準のScriptableObjectフィールド
インスペクタービュー:

ワークフロー:
- Projectウィンドウでイベントアセットを見つける(Event Database)
- インスペクターフィールドにドラッグ&ドロップ
推奨事項: より良いワークフローのために**[GameEventDropdown]**を使用してください—より速く、型安全です。
🎨 型付きイベント(引数付き)
イベントはアクションにデータを運ぶことができます。
Voidイベント(データなし)
[GameEventDropdown]
public GameEvent onGameStart;
void Start()
{
onGameStart.Raise(); // 引数なし
}
単一引数イベント
[GameEventDropdown]
public GameEvent<float> onHealthChanged;
private float health = 100f;
public void TakeDamage(float damage)
{
health -= damage;
onHealthChanged.Raise(health); // 現在のヘルス値を渡す
}
型安全性: ドロップダウンはGameEvent<float>イベントのみを表示し、型の不一致を防ぎます。
Sender + 引数イベント
[GameEventDropdown]
public GameEvent<GameObject, DamageInfo> onPlayerDamaged;
public void ApplyDamage(DamageInfo damageInfo)
{
// Sender = このGameObject、Args = ダメージ情報
onPlayerDamaged.Raise(this.gameObject, damageInfo);
}
使用例: アクションは誰がイベントをトリガーしたか、どのデータを処理するかを知る必要があります。
🔒 実行中の型安全性
ドロップダウンは、フィールド型に基づいてイベントを自動的にフィルタリングします:
public class ScoreManager : MonoBehaviour
{
[GameEventDropdown]
public GameEvent<int> onScoreChanged; // GameEvent<int>のみを表示
[GameEventDropdown]
public GameEvent<int> onLevelUp; // GameEvent<int>のみを表示
private int score = 0;
public void AddScore(int points)
{
score += points;
onScoreChanged.Raise(score); // 整数スコアを渡す
}
}
ドロップダウンフィルタリング:
GameEvent<int>の利用可能なイベント:
✅ OnScoreChanged (int)
✅ OnLevelUp (int)
✅ OnComboMultiplier (int)
❌ OnPlayerDeath (void) — フィルタリングされた(誤った型)
❌ OnDamage (float) — フィルタリングされた(誤った型)
なぜこれが重要か: 編集時に型エラーをキャッチし、実行時ではありません。
🔄 スケジュールされたイベントのキャンセル
イベントが遅延または繰り返し設定を使用している場合(**Game Event Behavior**で構成)、実行をキャンセルできます:
[GameEventDropdown]
public GameEvent repeatingSoundEvent;
void StartAmbientSound()
{
repeatingSoundEvent.Raise(); // 繰り返しを開始(Behavior構成に基づく)
}
void StopAmbientSound()
{
repeatingSoundEvent.Cancel(); // スケジュールされた実行を停止
}
使用例:
- プレイヤーがトリガーゾーンを離れる → アンビエントサウンドをキャンセル
- ゲームが一時停止 → タイミングイベントをキャンセル
- オブジェクトが破棄される → スケジュールされたアクションをクリーンアップ
🔧 高度: インスペクターリスナーコントロール
めったに必要ありませんが、実行時にインスペクター構成アクションを無効にできます:
[GameEventDropdown]
public GameEvent myEvent;
void DisableCutsceneUI()
{
myEvent.SetInspectorListenersActive(false);
// インスペクターアクションは発火しない、コードリスナーのみ
}
void EnableCutsceneUI()
{
myEvent.SetInspectorListenersActive(true);
// インスペクターアクションが再び発火
}
使用例:
- カットシーン中にUI更新を一時的に無効化
- ゲーム状態に基づいてアクションセット間を切り替え
💡 完全なワークフロー例
ビジュアルワークフローを使用して完全なドアシステムを構築しましょう。
ステップ1: イベントを作成
**Game Event Creator**で:

OnDoorOpened(voidイベント)を作成OnDoorClosed(voidイベント)を作成
ステップ2: アクションを構成
**Game Event Behavior**で:

OnDoorOpenedイベント:
- アクション:
AudioSource.PlayOneShot(doorOpenSound) - アクション:
Animator.SetTrigger("Open") - アクション:
ParticleSystem.Play()(ダストエフェクト)
OnDoorClosedイベント:
- アクション:
AudioSource.PlayOneShot(doorCloseSound) - アクション:
Animator.SetTrigger("Close")
ステップ3: スクリプトを書く
using TinyGiants.GameEventSystem.Runtime;
using UnityEngine;
public class DoorController : MonoBehaviour
{
[GameEventDropdown]
public GameEvent onDoorOpened;
[GameEventDropdown]
public GameEvent onDoorClosed;
private bool isOpen = false;
public void ToggleDoor()
{
if (isOpen)
{
isOpen = false;
onDoorClosed.Raise(); // すべてのアクションが自動的に発火
}
else
{
isOpen = true;
onDoorOpened.Raise(); // すべてのアクションが自動的に発火
}
}
// このメソッドは以下から呼び出すことができます:
// - インスペクターのボタンOnClick
// - Collision/Trigger検出
// - 他のゲームシステム
}
ステップ4: インスペクターでイベントを割り当て

DoorControllerGameObjectを選択- ドロップダウンを使用して
OnDoorOpenedイベントを割り当て - ドロップダウンを使用して
OnDoorClosedイベントを割り当て
完了! スクリプトにサウンド、アニメーション、VFX参照なし—すべて視覚的に構成。
🆚 なぜUnityEventsより優れているか?
従来のUnityEventアプローチには、ゲームイベントが解決する制限があります:
従来のUnityEventの制限
// ❌ 問題1: 多くのGameObjectにわたって分散された構成
public class Button1 : MonoBehaviour
{
public UnityEvent onClick; // Button1のインスペクターで構成
}
public class Button2 : MonoBehaviour
{
public UnityEvent onClick; // Button2のインスペクターで構成
}
// ❌ 問題2: すべての使用箇所を見つけるのが難しい
// シーン内のすべてのGameObjectを手動で検索する必要がある
// ❌ 問題3: 中央制御なし
// ボタンサウンドをグローバルに有効/無効化できない
// ❌ 問題4: 重複
// 50個のボタンで同じサウンド/VFXセットアップが繰り返される
ゲームイベントの利点
// ✅ 解決策: すべてのボタンが同じイベントを発火
public class ButtonController : MonoBehaviour
{
[GameEventDropdown]
public GameEvent onButtonClick; // すべてのボタンで同じイベント
public void OnClick()
{
onButtonClick.Raise();
}
}
利点:
| 機能 | UnityEvent | ゲームイベント |
|---|---|---|
| 集中構成 | ❌ GameObjectごと | ✅ 1つのEvent Behavior |
| すべての使用箇所を検索 | ❌ 手動検索 | ✅ Event Finder |
| グローバルコントロール | ❌ 50個のオブジェクトを変更 | ✅ 1つのイベントを変更 |
| 再利用性 | ❌ コピー&ペースト | ✅ 同じアセットを参照 |
| 条件ロジック | ❌ コードが必要 | ✅ ビジュアル条件ツリー |
| デバッグ | ❌ インスペクターのみ | ✅ フローグラフ視覚化 |
それぞれを使用するタイミング
UnityEventsを使用:
- シンプルな一回限りのコールバック(例: チュートリアルボタン)
- コンポーネント固有のロジック(例: スライダーが独自のラベルを更新)
- 再利用性が不要
ゲームイベントを使用:
- 再利用可能なロジック(例: すべてのボタンクリックが同じサウンドを再生)
- 複雑なシーケンス(例: カットシーン、ドアパズル)
- 中央制御が必要(例: すべてのUIサウンドをミュート)
- ビジュアルデバッグが必要(フローグラフ)
❓ トラブルシューティング
ドロップダウンに「Manager Missing」と表示
原因: シーンにGameEventManagerがありません。
解決策:
Unityツールバーから Game Event System を開きます:
Tools > TinyGiants > Game Event System
「Initialize Event System」ボタンをクリックすると、シーンにGame Event Manager GameObject(シングルトン)が作成されます。
ドロップダウンに「No Active Databases」と表示
原因: GameEventManagerにデータベースが割り当てられていません。
解決策:
- シーンで
GameEventManagerを選択 - インスペクター → Databasesセクション
- イベントデータベースを追加
ドロップダウンに「No Matching Events」と表示
原因: フィールド型に一致するイベントがありません。
例:
[GameEventDropdown]
public GameEvent<string> textEvent; // GameEvent<string>が必要
// しかし、データベースには以下のみがあります:
// - GameEvent (void)
// - GameEvent<int>
// - GameEvent<float>
結果: 一致するイベントなし!
解決策: Game Event Creatorを使用して正しい型のイベントを作成します。
イベントが発火しない
チェックリスト:
- ✅ イベントアセットがインスペクターで割り当てられているか?
- ✅
Raise()が呼び出されているか?(Debug.Logを追加して確認) - ✅ アクションがGame Event Behaviorで構成されているか?
- ✅ 条件が満たされているか?(条件ツリーを確認)
- ✅ GameEventManagerがシーンにあるか?
これで完全なビジュアルワークフローを学びました:
- ✅ Event Creatorでイベントを作成
- ✅ Event Behaviorでアクションを構成
- ✅ UnityEventsまたは
GameEventDropdownでイベントを発火
結果: 疎結合で、保守可能な、デザイナーフレンドリーなゲームロジック!
このページはビジュアルワークフロー(インスペクター割り当てでスクリプト内のイベントを発火)をカバーしています。高度なコード技術(実行時リスナー、条件トリガー、イベントチェーン)については、**Runtime API**を参照してください。