Unity 事件中心(Event Center)详解

在 Unity 开发中,不同模块之间的通信 是一个重要的挑战。传统的直接调用观察者模式 有时会导致代码耦合过高,难以维护。

事件中心(Event Center) 是一种解耦的消息机制,允许不同组件之间低耦合地传递信息,从而提高代码的可维护性和扩展性

本篇博客将详细介绍 事件中心的概念、使用场景、实现方式,以及在 Unity 中的应用


1. 什么是事件中心?

事件中心(Event Center)是一种基于委托(Delegate)和事件(Event) 的消息管理系统,核心思想是发布-订阅模式(Publish-Subscribe)

它包含两个主要部分:

  1. 发布者(Publisher) - 触发事件的对象(如玩家拾取道具、NPC 说话)
  2. 订阅者(Subscriber) - 监听并响应事件的对象(如 UI 显示道具、任务系统更新)

事件中心的工作流程

[事件中心]  
 ├── 订阅者 1 监听 "敌人死亡" 事件  
 ├── 订阅者 2 监听 "敌人死亡" 事件  
 ├── 事件触发 → "敌人死亡" 事件广播  
 ├── 订阅者 1 & 订阅者 2 同时执行回调

优点
解耦:模块之间无需直接依赖,事件触发后自动通知所有监听者
易扩展:新功能只需注册监听事件,不影响原有代码
灵活性强:支持多种事件类型(UI、AI、游戏逻辑)


2. 事件中心的使用场景

事件中心适用于 多个系统需要监听同一事件 的情况,例如:

  • UI 更新:玩家拾取道具,UI 更新显示
  • 任务系统:玩家完成目标,任务系统检测完成状态
  • 敌人 AI:某个敌人死亡,所有监听者都能收到消息
  • 音效管理:某些动作触发时,播放相应的音效

3. 在 Unity 中实现事件中心

Unity 提供了 C# 委托(Delegate)和事件(Event),可以用来构建事件中心。

① 基于 C# 事件的简单事件中心

适用于 小型项目简单的事件管理

using System;

public static class EventCenter
{
    public static event Action<int> OnEnemyDead; // 事件:敌人死亡(带参数)

    public static void EnemyDead(int enemyID)
    {
        OnEnemyDead?.Invoke(enemyID); // 触发事件
    }
}

// 订阅者 1:UI 更新
public class EnemyUI
{
    public EnemyUI() { EventCenter.OnEnemyDead += UpdateUI; }
    private void UpdateUI(int enemyID) => Console.WriteLine($"敌人 {enemyID} 死亡,更新 UI!");
}

// 订阅者 2:任务系统
public class QuestSystem
{
    public QuestSystem() { EventCenter.OnEnemyDead += CheckQuest; }
    private void CheckQuest(int enemyID) => Console.WriteLine($"敌人 {enemyID} 死亡,检查任务完成情况!");
}

// 测试
public class Game
{
    public static void Main()
    {
        EnemyUI ui = new EnemyUI();
        QuestSystem quest = new QuestSystem();

        EventCenter.EnemyDead(101); // 触发事件,通知所有监听者
    }
}

效果

敌人 101 死亡,更新 UI!
敌人 101 死亡,检查任务完成情况!

特点
✅ 代码简单,适合小项目
不支持动态事件管理(无法动态添加/移除事件类型)


② 基于 Dictionary 的通用事件中心

适用于 中大型项目,可以支持任意类型的事件

using System;
using System.Collections.Generic;

public class EventCenter
{
    private static Dictionary<string, Action<object>> eventDict = new Dictionary<string, Action<object>>();

    public static void AddListener(string eventName, Action<object> listener)
    {
        if (!eventDict.ContainsKey(eventName))
            eventDict[eventName] = null;
        eventDict[eventName] += listener;
    }

    public static void RemoveListener(string eventName, Action<object> listener)
    {
        if (eventDict.ContainsKey(eventName))
            eventDict[eventName] -= listener;
    }

    public static void TriggerEvent(string eventName, object param = null)
    {
        if (eventDict.ContainsKey(eventName))
            eventDict[eventName]?.Invoke(param);
    }
}

// 订阅者 1:UI 更新
public class EnemyUI
{
    public EnemyUI() { EventCenter.AddListener("EnemyDead", UpdateUI); }
    private void UpdateUI(object enemyID) => Console.WriteLine($"敌人 {enemyID} 死亡,更新 UI!");
}

// 订阅者 2:任务系统
public class QuestSystem
{
    public QuestSystem() { EventCenter.AddListener("EnemyDead", CheckQuest); }
    private void CheckQuest(object enemyID) => Console.WriteLine($"敌人 {enemyID} 死亡,检查任务完成情况!");
}

// 测试
public class Game
{
    public static void Main()
    {
        EnemyUI ui = new EnemyUI();
        QuestSystem quest = new QuestSystem();

        EventCenter.TriggerEvent("EnemyDead", 101);
    }
}

效果

敌人 101 死亡,更新 UI!
敌人 101 死亡,检查任务完成情况!

特点
支持动态注册和移除事件(适合大型项目)
事件名称自由,支持多个事件类型
低耦合,更适合模块化开发


4. 事件中心 vs 其他通信方式

通信方式优势劣势适用场景
直接调用简单,直观高耦合,扩展性差单个类之间的调用
单例模式方便访问全局对象可能导致全局依赖共享数据(如 UI 管理器)
观察者模式低耦合,支持多监听代码较复杂事件通知机制
事件中心解耦、灵活、扩展性强可能导致过多事件大型项目、多人协作

5. 结论

事件中心的核心优势

模块解耦,各个系统之间无需直接依赖
提高扩展性,可以方便地增加新的监听者
支持多个事件类型,可灵活管理游戏逻辑

什么时候使用事件中心?

🔹 需要多个系统监听同一事件时(UI、任务系统、音效管理等)
🔹 需要解耦不同模块的依赖关系时
🔹 希望提高代码的扩展性和可维护性时

在 Unity 开发中,事件中心是一种非常强大的工具,掌握它可以让你的游戏架构更加清晰,开发效率更高!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值