事件機制EventSystem ECS最重要的特性一是數據跟邏輯分離,二是數據驅動邏輯。什麼是數據驅動邏輯呢?不太好理解,我們舉個例子 一個moba游戲,英雄都有血條,血條會在人物頭上顯示,也會在左上方頭像UI上顯示。這時候服務端發來一個扣血消息。我們怎麼處理這個消息?第一種方法,在消息處理函數中修 ...
事件機制EventSystem
ECS最重要的特性一是數據跟邏輯分離,二是數據驅動邏輯。什麼是數據驅動邏輯呢?不太好理解,我們舉個例子 一個moba游戲,英雄都有血條,血條會在人物頭上顯示,也會在左上方頭像UI上顯示。這時候服務端發來一個扣血消息。我們怎麼處理這個消息?第一種方法,在消息處理函數中修改英雄的血數值,修改頭像上血條顯示,同時修改頭像UI的血條。這種方式很明顯造成了模塊間的耦合。第二種方法,扣血消息處理函數中只是改變血值,血值的改變拋出一個hpchange的事件,人物頭像模塊跟UI模塊都訂閱血值改變事件,在訂閱的方法中分別處理自己的邏輯,這樣各個模塊負責自己的邏輯,沒有耦合。 ET提供了多種事件,事件都是可以多次訂閱的:
- AwakeSystem,組件工廠創建組件後拋出,只拋出一次,可以帶參數
Player player = ComponentFactory.Create<Player>(); // 訂閱Player的Awake事件 public class PlayerAwakeSystem: AwakeSystem<Player> { public override void Awake(Player self) { } }
- StartSystem,組件UpdateSystem調用前拋出
// 訂閱Player的Start事件 public class PlayerStartSystem: StartSystem<Player> { public override void Start(Player self) { } }
- UpdateSystem,組件每幀拋出
// 訂閱Player的Update事件 public class PlayerUpdateSystem: UpdateSystem<Player> { public override void Update(Player self) { } }
- DestroySystem,組件刪除時拋出
// 訂閱Player的Destroy事件 public class PlayerDestroySystem: DestroySystem<Player> { public override void Destroy(Player self) { } } Player player = ComponentFactory.Create<Player>(); // 這裡會觸發Destroy事件 player.Dispose();
- ChangeSystem,組件內容改變時拋出,需要開發者手動觸發
// 訂閱Player的Destroy事件 public class PlayerChangeSystem: ChangeSystem<Player> { public override void Change(Player self) { } } Player player = ComponentFactory.Create<Player>(); // 需要手動觸發ChangeSystem Game.EventSystem.Change(player);
- DeserializeSystem,組件反序列化之後拋出
// 訂閱Player的Deserialize事件 public class PlayerDeserializeSystem: DeserializeSystem<Player> { public override void Deserialize(Player self) { } } // 這裡player2會觸發Deserialize事件 Player player2 = MongoHelper.FromBson<Player>(player.ToBson());
- LoadSystem,EventSystem載入dll時拋出,用於服務端熱更新,重新載入dll做一些處理,比如重新註冊handler
// 訂閱Player的Load事件 public class PlayerLoadSystem: LoadSystem<Player> { public override void Load(Player self) { } }
- 普通的Event,由開發者自己拋出,可以最多帶三個參數。另外客戶端熱更層也可以訂閱mono層的Event事件
int oldhp = 10; int newhp = 5; // 拋出hp改變事件 Game.EventSystem.Run("HpChange", oldhp, newhp); // UI訂閱hp改變事件 [Event("HpChange")] public class HpChange_ShowUI: AEvent<int, int> { public override void Run(int a, int b) { throw new NotImplementedException(); } } // 模型頭頂血條模塊也訂閱hp改變事件 [Event("HpChange")] public class HpChange_ModelHeadChange: AEvent<int, int> { public override void Run(int a, int b) { throw new NotImplementedException(); } }
- 除此之外還有很多事件,例如消息事件。消息事件使用MessageHandler來聲明,可以帶參數指定哪種伺服器需要訂閱。
[MessageHandler(AppType.Gate)] public class C2G_LoginGateHandler : AMRpcHandler<C2G_LoginGate, G2C_LoginGate> { protected override void Run(Session session, C2G_LoginGate message, Action<G2C_LoginGate> reply) { G2C_LoginGate response = new G2C_LoginGate(); reply(response); } }
更具體的消息事件等到講消息的時候再細細講解了
10. 數值事件,數值模塊再講解
......, 更多的事件由自己去開發。
ET框架的邏輯就是由以上各種事件來驅動的。
ET開源地址地址:egametang/ET: Unity3D Client And C# Server Framework (github.com) qq群:474643097