Unity 事件驱动架构

在 Unity 中,很多人会用 UnityEvent(性能极差、产生大量 GC)或者 Dictionary<Type, Delegate>(有装箱拆箱开销、字典查找开销)来写事件中心。

但如果你追求 极致性能和优雅 ,当今 C# 最强悍的事件总线写法是利用 泛型静态类 。这种写法 不需要字典查找,不需要强转类型,0 GC 产生 !🏆

1. 定义事件(使用 struct 避免 GC)

首先,我们把事件定义为 结构体(struct) 。由于结构体分配在栈(Stack)上,所以每次发布事件时都不会产生任何堆内存垃圾(Zero GC)。

cs 复制代码
// 定义一个玩家死亡事件,里面可以携带任何你需要的数据
public struct PlayerDeathEvent
{
    public string KillerName;
    public int DamageTaken;
}

// 另一个事件例子:获得金币
public struct CoinCollectedEvent
{
    public int Amount;
}
2. 极致性能的 EventBus 核心类

利用 C# 的泛型特性,EventBus<T> 会为每一个不同的 T 生成一个独立的静态类。这就是它不需要字典却能完美分类事件的黑魔法

cs 复制代码
using System;

public static class EventBus<T> where T : struct
{
    // 利用 Action<T> 存储订阅者方法
    private static Action<T> OnEvent;

    // 订阅事件
    public static void Subscribe(Action<T> handler)
    {
        OnEvent += handler;
    }

    // 取消订阅
    public static void Unsubscribe(Action<T> handler)
    {
        OnEvent -= handler;
    }

    // 发布事件
    public static void Publish(T eventMessage)
    {
        OnEvent?.Invoke(eventMessage);
    }
}
3. 发布者(Publisher)如何使用?

现在,Player 的代码变得极其干净,它完全不知道其他系统的存在。

cs 复制代码
using UnityEngine;

public class Player : MonoBehaviour
{
    public void Die()
    {
        Debug.Log("玩家倒下了...");
        
        // 仅仅是发布一个结构体事件,0 GC,极其快速
        EventBus<PlayerDeathEvent>.Publish(new PlayerDeathEvent 
        { 
            KillerName = "大魔王", 
            DamageTaken = 9999 
        });
    }
}
4. 订阅者(Subscriber)如何使用?

各个系统自己管好自己的事情,在初始化时订阅,在销毁时 必须 取消订阅。

cs 复制代码
using UnityEngine;

public class AchievementManager : MonoBehaviour
{
    private void OnEnable()
    {
        // 开启监听
        EventBus<PlayerDeathEvent>.Subscribe(OnPlayerDeath);
    }

    private void OnDisable()
    {
        // ⚠️ 极其重要:对象销毁或禁用时,必须取消监听,否则会导致内存泄漏!
        EventBus<PlayerDeathEvent>.Unsubscribe(OnPlayerDeath);
    }

    private void OnPlayerDeath(PlayerDeathEvent evt)
    {
        Debug.Log($"[成就系统] 记录玩家被 {evt.KillerName} 击杀,承受了 {evt.DamageTaken} 点伤害。");
        // 执行解锁成就等逻辑...
    }
}
相关推荐
AI前沿资讯1 小时前
一站式 AI 3D 创作首选:V2Fun—— 直连 Unity + 多人动捕双核心,重塑轻量化生产管线
人工智能·3d·unity
winlife_10 小时前
Unity 域重载会清空一切:Editor 工具如何让状态在重载后续命
unity·游戏引擎
小贺儿开发12 小时前
Unity3D 串口通信上位机联调系统
unity·串口·协议·数据·通信·传输·互动
垂葛酒肝汤1 天前
Unity的UI扫光效果Shader
ui·unity·游戏引擎
mxwin2 天前
Unity Shader Alpha测试 · 模板测试 · 深度测试
unity·游戏引擎
Sator12 天前
unity解决粒子与物体接触时的硬边缘问题
unity·游戏引擎
程序员JerrySUN2 天前
Jetson边缘嵌入式实战课程第三讲:L4T 与 Jetson 系统架构
linux·服务器·人工智能·安全·unity·系统架构·游戏引擎
萌萌的提莫队长2 天前
Unity HDRP 渲染管线 Camera 输出到RenderTexture没有Alpha通道
unity·游戏引擎
winlife_2 天前
Unity Editor 工具不该用反射写组件字段:SerializedObject 在 4 个场景里非用不可
unity·自动化·游戏引擎
星河耀银海2 天前
Unity C#入门:变量的定义与访问权限(public/private)
unity·c#·lucene