事件中心是什么
事件中心是 Unity 游戲開發中常用的架構設計,它基于觀察者模式?或?發布-訂閱模式,通過委托和事件構建的一種消息管理系統。主要用于降低代碼耦合度,實現模塊間的松耦合通信的消息處理系統能大幅提升代碼的可維護性和擴展性,允許不同腳本在不直接引用彼此的情況下進行交互。
作用
1. 解耦代碼,減少直接依賴
傳統方式:A 腳本調用 B 腳本的方法,需要?GetComponent<B>()?或持有 B 的引用。
事件中心方式:A 觸發事件,B 監聽事件,兩者無需互相知道對方存在。
2. 全局通信
任何腳本都可以監聽或觸發事件,適合跨場景、跨系統的通信(如UI更新、游戲狀態變化、敵人死亡通知等)。
3. 動態管理事件
可以隨時添加/移除事件監聽,避免硬編碼調用關系。
適合動態場景(如玩家死亡后取消某些監聽)。
4. 支持多參數傳遞
事件可以攜帶數據(如 int?damage、string playerName、Vector3 position?等)。
應用場景
1. 游戲邏輯(如敵人死亡、任務完成)
2. UI交互(如按鈕點擊、數據更新)
3. 場景切換(如清理事件緩存)
實現方式
EventCenter 代碼可直接食用,無需掛載在場景中,可供全局使用。
該消息中心設置了一個不限返回數據類型的委托? ? params object[] msg;
同時將消息名和對應的回調方法以鍵值對的方式存儲在字典中? ? Dictionary<string, EventHandler>;
消息中心除了在觸發相應事件的時候調用相應的回調函數,還能傳回不同類型、數量的數據。
using UnityEngine;
using System.Collections.Generic;public static class EventCenter
{// 事件委托定義,用于回調函數,參數為object數組,返回值為空public delegate void EventHandler(params object[] msg);// 消息字典private static Dictionary<string, EventHandler> messageDic = new Dictionary<string, EventHandler>();// 注冊消息監聽public static void AddListener(string msgName, EventHandler eventHandler){if (messageDic.ContainsKey(msgName)){messageDic[msgName] += eventHandler;}else{messageDic.Add(msgName, eventHandler);}}// 注銷消息監聽public static void RemoveListener(string msgName, EventHandler eventHandler){if (messageDic.ContainsKey(msgName)){messageDic[msgName] -= eventHandler;if (messageDic[msgName] == null){messageDic.Remove(msgName);}}}// 觸發消息public static void TriggerEvent(string msgName, params object[] msg){if (messageDic.TryGetValue(msgName, out EventHandler eventHandler)){eventHandler.Invoke(msg);}else{Debug.Log("消息" + msgName + "未注冊");}}// 清空所有消息監聽public static void Clear(){messageDic.Clear();}
}
?使用方法
先注冊消息,開始監聽事件。根據需求注銷消息,取消監聽事件。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class GameManager: MonoBehaviour
{private void Start(){// 注冊消息EventCenter.AddListener("startGame", StartGame);}private void OnDestroy(){// 注銷消息EventCenter.RemoveListener("startGame", StartGame);}// 被監聽的事件所對應的方法需要有一個與委托對應的參數類型 object[] args = nullpublic void StartGame(object[] args = null){if (args != null){foreach (var arg in args){Debug.Log(arg);}}Debug.Log("Start Game");}
}
觸發消息,觸發監聽事件。同時,下面設置了三個用例,在觸發回調函數的同時還傳回相關參數。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test: MonoBehaviour
{private void Update(){if (Input.GetKeyDown(KeyCode.J)){Test1();}if (Input.GetKeyDown(KeyCode.K)){Test2();}if (Input.GetKeyDown(KeyCode.L)){Test3();}}void Test1(){// 觸發消息EventCenter.TriggerEvent("startGame");}void Test2(){// 觸發消息EventCenter.TriggerEvent("startGame", 1);}void Test3(){// 觸發消息EventCenter.TriggerEvent("startGame", 1, "test");}
}
?