メインコンテンツまでスキップ

ゲームイベントビヘイビア

イベントが発火したときに何が起こるかを定義します。盲目的に実行される従来のイベントとは異なり、このシステムでは、条件、遅延、ループ、およびビジュアルアクションをイベントアセット自体に直接アタッチできます。

Game Event Behavior Window


🚀 Behaviorウィンドウを開く

**Game Event Editor**からアクセス:

Game Event Editor → 任意のイベント行のBehaviorボタン(カラーピル)をクリック

ボタンの色の状態:

アイコン意味詳細
🟢 緑構成済み(インスペクター)ManagerにUnityEventアクションあり
🔵 青実行時アクティブ(プレイモード)AddListener()を介したコードベースのリスナーあり
🟡 オレンジ未構成アクションまたはリスナーなし

ボタンラベル: イベント型シグネチャを表示(例: <void><int><GameObject, DamageInfo>)


📋 ウィンドウ概要

Behaviorウィンドウには4つの主要セクションがあります:

  1. Event Information - 識別確認(名前、カテゴリ、GUID)
  2. Action Condition - ビジュアルロジックツリー(実行ゲート)
  3. Event Action - UnityEventコールバック(実行内容)
  4. Schedule Configuration - タイミングコントロール(遅延、ループ、永続性)

1️⃣ Event Information

正しいイベントを編集していることを確認する読み取り専用の要約。

Event Information

表示データ:

  • Event Name: アセット名
  • Category: 組織グループ
  • GUID: 一意の内部識別子(リネーム間で保持)
GUIDが重要な理由

GUIDは、イベントの名前を変更してもリファレンスが無傷のままであることを保証します。これがEditorでの安全なリネーミングが機能する理由です!


2️⃣ Action Condition(実行ゲート)

ロジックエンジン: これらの条件がTRUEと評価された場合にのみアクションが実行されます。

Action Condition Section

動作内容

実行時の値に基づいてアクションが実行されるかどうかを制御します:

ビジュアルロジックツリー

コードなしで複雑なブール論理を構築:

  • グループ: AND/ORロジックで条件を結合
  • 比較: 個別チェック(例: Health < 20)
  • ネスト: グループ内のグループ(無制限の深さ)

パフォーマンス

ゼロリフレクションオーバーヘッド

条件は初期化時にExpression Treeにコンパイルされます。手書きのC#コードと同じ速さで実行されます!

詳細を学ぶ

ビジュアル条件ツリーは多くの機能を持つ強力なシステムです:

  • 4つのソースタイプ: イベント引数、シーン型、ランダム、定数
  • 10の比較演算子: 数値、文字列、コレクションチェック
  • Boolメソッドサポート: カスタムboolメソッドを条件として使用
  • ドラッグ&ドロップ並べ替え: ロジックを視覚的に整理
  • 型検証: 互換性のない比較を自動検出

📖 完全ガイド: Visual Condition Tree


3️⃣ Event Action(コールバックレイヤー)

Actionは、イベントがトリガーされ、すべての条件が満たされた後に実行されるUnityコールバックを定義します。

alt text

🧩 UnityEventフィールドの理解

システムはUnityのネイティブUnityEventアーキテクチャを活用し、既存のMonoBehaviourやUIコンポーネントとのシームレスな統合を保証します。


🔘 パラメータなしイベント(GameEvent)の場合

標準トリガーのみのロジック。

タイプバックエンドフィールド互換性
ロジックUnityEvent (void)🟢 任意のゼロパラメータメソッドを受け入れます。

例: OnGameStart ➔ AudioManager.PlayBGM()、UI.FadeIn()


🔢 シングルパラメータイベント(GameEvent<T>)の場合

ペイロード駆動ロジック。リスナーにデータを直接渡します。

タイプバックエンドフィールド互換性
ロジックUnityEvent<T>🟡 型Tの1つのパラメータを持つメソッドを受け入れます。

例: OnHealthChanged(float) ➔ HealthBar.UpdateFill(float)


👥 Senderイベント(GameEvent<TSender, TArgs>)の場合

コンテキスト認識ロジック。ソースとデータペイロードの両方を渡します。

タイプバックエンドフィールド互換性
ロジックUnityEvent<TSender, TArgs>🔵 2つのパラメータを持つメソッドを受け入れます。

例: OnDamage(GameObject, int) ➔ VFXManager.SpawnAt(GameObject.pos)、Popup.Show(int)

ネイティブ統合

ネイティブUnityEventsを使用するため、インスペクターで直接リスナーを割り当てるか、AddListener()を使用してコードで割り当てることができます。静的および動的呼び出しの両方をサポートします。

シグネチャマッチング

インスペクターUIは、イベントのシグネチャに一致する関数のみを表示するようにメソッドリストを自動的にフィルタリングし、実行時エラーを防ぎます。


➕ アクションの追加(ワークフロー)

alt text

Unityインスペクターを介してロジックを接続するための3つの簡単なステップに従ってください。

1️⃣ ターゲットオブジェクトを割り当て

ロジックを含むGameObjectまたはComponentをObjectスロットにドラッグ&ドロップします。

  • 🖱️ アクション: HierarchyからドラッグしてEmptyスロットにドロップ。
  • 📦 結果: フィールドがスクリプトの特定のインスタンスを参照するようになります。

2️⃣ コールバックメソッドを選択

Function Dropdownをクリックして、割り当てられたオブジェクトで利用可能なすべてのパブリックメソッドを参照します。

  • 🔍 アクション: No Functionをクリック ➔ スクリプト/コンポーネントに移動。
  • ヒント: イベントシグネチャ(例: void、int)に一致するメソッドのみが簡単に選択できるように上部に表示されます。

3️⃣ パラメータマッピングを定義

イベントのライブデータを使用するか、固定値を使用するかを決定します。

  • ⚖️ Dynamic Call: イベントによって送信される実行時の値を使用します(例: 実際に与えられたダメージ)。
  • ⚙️ Static Parameters: インスペクターで手動で定義した固定値を使用します。

💡 Dynamic vs Static: どちらを選ぶ?

モードビジュアルアイコン最適な用途...
Dynamic🚀リアルタイムデータ(例: 現在のHPでHealth Barを更新)。
Static📌固定トリガー(例: コンソールに「Button Clicked」をログ記録)。
プロのヒント

ドロップダウンでは、Dynamicメソッドは常にメニューの上部にリストされます。そこにメソッドが表示されない場合は、パラメータ型が正確に一致しているか確認してください!


Dynamic vs Static関数

Dynamic(イベントデータ付き):

// イベントパラメータを受け取る
public void TakeDamage(float amount) {
health -= amount;
}

// Senderイベントの場合
public void OnDamageReceived(GameObject attacker, DamageInfo info) {
// senderとargsの両方を使用
}

Static(イベントデータを無視):

// パラメータ不要
public void PlaySound() {
audioSource.Play();
}

それぞれを使用するタイミング:

Dynamicを使用する場合Staticを使用する場合
イベントのデータが必要通知のみが必要
float/int値の処理サウンド/エフェクトの再生
Sender参照の確認アニメーションのトリガー
データ駆動の反応状態変更

複数のアクション&優先度

複数追加: +を繰り返しクリックしてアクションを追加。

実行順序: 上から下へ。

並べ替え: 各アクションの左側にある☰ハンドルをドラッグ。

:

📜 LogDamageEvent()
🥇 最初(メタデータ/ログ記録)
🎵 PlayHitSound()
🥈 2番目(オーディオ/VFXフィードバック)
📊 UpdateHealthBar(float)
🥉 3番目(UI/ビジュアル表現)
🏁 CheckDeathCondition()
🏆 最後(ゲーム状態ロジック)

すべてのアクションをクリア

**「Clear All」**ボタン(右上)をクリックして、すべてのアクションを一度に削除。

⚠️ 確認を表示: 「本当によろしいですか?」


4️⃣ Schedule Configuration

Scheduleレイヤーは、イベントが発火した後、アクションがいつどのくらいの頻度で実行されるかを決定します。

alt text

アクション遅延

時間オフセット。 イベントトリガーと実際の実行の間にギャップを導入します。

  • 🕒 値: float(秒)
  • 🎯 目的: アニメーション、VFX、または遅延ゲームロジックと同期。

動作方法:

  1. 🔔 イベント発火 ➔ シグナルが受信されます。
  2. 遅延中 ➔ システムが指定されたX秒間待機します。
  3. 🔍 条件チェック ➔ 待機に条件を再検証します。
  4. 🚀 実行 ➔ 条件がまだ満たされている場合にのみアクションが発火します。

❓ トラブルシューティング

アクションが実行されない

問題: イベントが発火するが何も起こらない。

チェックリスト:

条件を確認:

1. 条件が有効になっているか?(条件セクションで切り替え)
2. 条件がTRUEと評価されるか?
3. 条件ロジックをテスト - Visual Condition Treeガイドを参照
4. Debug.Log()を追加して値を確認

アクションを確認:

1. UnityEventフィールドが空か?アクションを追加!
2. ターゲットGameObjectが破棄されているか?
3. ターゲットComponentが無効になっているか?
4. エラーについてコンソールを確認

スケジュールを確認:

1. アクション遅延が長すぎるか?
2. 繰り返し間隔が混乱を引き起こしているか?
3. イベントが不適切に永続化されているか?

「Field Not Found」警告

問題: Field 'IntGameEventAction' not found.

原因: イベント型がバインディングコードを欠いている。

解決策:

**「Force Rebuild All (Fix Missing Bindings)」**ボタンをクリック。

これによりすべてのバインディングフィールドが再生成されます:

Assets/TinyGiantsData/GameEventSystem/CodeGen/Basic/
└─ IntGameEvent.cs (バインディングフィールド付きで再生成)

コンパイル後: Behaviorウィンドウを再度開く。


アクションが複数回発火する

問題: アクションが予想以上に実行される。

一般的な原因:

原因1: 繰り返し設定

確認:
- 繰り返し間隔 > 0?
- 繰り返し回数 > 0?

はいの場合、イベントはループしています(意図的または偶発的)

原因2: 複数のイベントRaise

イベントがコード内で複数回発火:
OnHealthChanged.Raise(newHealth); ← 繰り返し呼び出される

解決策: イベントが必要なときにのみ発火することを確認

原因3: 複数のリスナー

UnityEventに同じアクションが複数回追加されている

解決策: アクションリストを確認し、重複を削除

次のステップ

イベントビヘイビアを理解したので、**Visual Condition Treeを探索して高度な条件ロジックをマスターしてください。またはFlow Editor**にジャンプしてイベントオーケストレーションを構築しましょう!