# 3-2.事件模块 - GameEvent 高效且无GC的事件系统GameEvent,可以指定事件ID/事件String监听和分发事件。通过事件来驱动模块,如战斗的角色身上的事件流、UI和网络以及Model的数据流、开发中的绝大部分情况都可以通过事件来进行驱动。(配合UI模块或者拓展的战斗模块实现MVE[Model - View - Event]事件驱动架构) 事件模块支持string和int作为事件Id,但推荐是使用int因为可以避免事件字典的哈希碰撞。这里实现了StringId.StringToHash的方法来定义事件ID达到事件系统的最佳性能。 注:UI模块的事件和UI生命周期存在绑定,销毁UI时可以自动移除UI所监听的事件,开发过程中只需要关心添加事件,避免了关闭UI但没有移除事件监听的问题,角色模块也可以参考实现。(AddUIEvent) ``` csharp public static readonly int Hellp = StringId.StringToHash("Hellp.Hellp"); class A { public A() { //添加事件监听string GameEvent.AddEventListener("TEngine很好用",TodoSomeThings); //添加事件监听int 事件ID GameEvent.AddEventListener(Hellp,TodoSomeThings2); } } class B { private void SaySomeThings() { //发送事件流 GameEvent.Send("TEngine很好用"); GameEvent.Send(Hellp); } } 【举个例子:游戏中血量扣除的时候,服务器发来了一个减少Hp的消息包, 我们可以在收到这个消息包的时候发送一个事件流,在玩家头顶的HP进度 条组件/左上角Hp的UI血条组件添加一个监听事件,各个模块负责自己监听后的逻辑】 Server -> SendMessage(ReduceHP) class ClientHandle { private void HandleMessage(MainPack mainpack) { ... HpPack hpPack = mainpack.hpPack; int playerId = mainpack.playerId; var player = PlayerMgr.Instance.GetPlayer(playerId); if(player != null){ player.Event.Send("Hpchange",hpPack); //局部的事件管理器 GameEvent.Send("Hpchange",hpPack); //全局事件中心 } } } class PlayerHp { public ECSEventCmpt Event { get; set; } PlayerHp(){ Event.AddEventListener(Hellp,HandleUpChange); } } [Window(UILayer.UI)] class BattleMainUI: UIWindow { public override void RegisterEvent() { AddUIEvent(Hellp,HandleUpChange); } public void HandleUpChange(HpPack pack){} } ```