NumericFactory/Books/3-2-事件模块.md
2025-04-21 21:14:23 +08:00

69 lines
2.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 3-2.事件模块 - GameEvent
高效且无GC的事件系统GameEvent可以指定事件ID/事件String监听和分发事件。通过事件来驱动模块如战斗的角色身上的事件流、UI和网络以及Model的数据流、开发中的绝大部分情况都可以通过事件来进行驱动。(配合UI模块或者拓展的战斗模块实现MVE[Model - View - Event]事件驱动架构)
事件模块支持string和int作为事件Id但推荐是使用int因为可以避免事件字典的哈希碰撞。这里实现了StringId.StringToHash的方法来定义事件ID达到事件系统的最佳性能。
<strong>UI模块的事件和UI生命周期存在绑定销毁UI时可以自动移除UI所监听的事件,开发过程中只需要关心添加事件避免了关闭UI但没有移除事件监听的问题角色模块也可以参考实现。(AddUIEvent)</strong>
``` 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<HpPack>(Hellp,HandleUpChange);
}
}
[Window(UILayer.UI)]
class BattleMainUI: UIWindow
{
public override void RegisterEvent()
{
AddUIEvent<HpPack>(Hellp,HandleUpChange);
}
public void HandleUpChange(HpPack pack){}
}
```