UFL4——事件中心模块

前置知识点

  1. C#中Dictionary​相关知识点(C#四部曲之C#进阶中)
  2. C#中委托事件相关知识点(C#四部曲之C#进阶中)
  3. C#中泛型相关知识点(C#四部曲之C#进阶中)
  4. C#中里式替换原则(C#四部曲之C#核心中)
  5. 观察者设计模式

事件中心模块

  1. 事件中心的主要作用

    解耦程序模块,降低程序耦合度,它可以降低游戏中不同模块的耦合度
    不需要直接引用或依赖于彼此的具体实现

  2. 事件中心的基本原理

    利用字典和委托相关的知识点,再结合观察者设计模式的基本原理
    实现一个中心化的机制,使得多个系统、模块、对象之间可以进行松耦合的通信

举例抛出问题

在以前,没有事件中心的时候,
面对一个对象被修改时其它对象要做自动更新的问题:
例如一个怪物死亡,需要让其它对象例如玩家执行什么方法,
我们可能就会让怪物关联这些对象,然后在死亡的方法里调用这些对象

image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using UnityEngine;

public class Monster : MonoBehaviour
{
void Start()
{
Dead();
}

void Dead()
{
Debug.Log("怪物死亡了");
//其他对象在怪物死亡时要做的事情
//1.任务更新
GameObject.Find("Task").GetComponent<Task>().TaskWaitMonsterDeadDo();
//2.玩家得奖励
GameObject.Find("Player").GetComponent<Player>().PlayerWaitMonsterDeadDo();
//3.其他相关系统
GameObject.Find("Other").GetComponent<Other>().OtherWaitMonsterDeadDo();
//n个其他相关处理..
//...
}
}

目前这种常规处理方式,我们发现了问题:系统、模块和对象之间耦合度较高
目前只是怪物死亡的例子,就发现对象和模块之间会出现彼此相互引用和依赖
那么当游戏复杂了,各个系统、模块、对象之间会存在错综复杂的关系,非常不利于我们进行开发

而且显然,怪物对象死亡后其他对象要做什么显然也不应该在怪物类里去找各个对象一个一个执行

事件中心的主要作用

事件中心的主要作用是:解耦程序模块,降低程序耦合度,它可以降低游戏中不同模块的耦合度,不需要直接引用或依赖于彼此的具体实现

事件中心可以让需要监听某个事件的执行者主动上传监听到事件后要执行的方法,等待事件的触发,而不需要关心谁触发这个事件
而事件的触发者只需要向事件中心触发事件,而无需关心有哪些对象需要监听这个事件

由此,触发者不再需要主动关联很多对象,达到了解耦的目的

事件中心的基本原理

事件中心的基本原理:通过一个中心化的机制,使得多个系统、模块、对象之间可以进行松耦合的通信
我们只需要利用字典和委托相关的知识点,再结合观察者设计模式的基本原理便可以制作出事件中心模块

image

观察者设计模式

观察者模式 | 菜鸟教程 (runoob.com)

观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新

image

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)
比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者模式属于行为型模式。

意图: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决: 一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用: 一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

优点:
1、观察者和被观察者是抽象耦合的。
2、建立一套触发机制。

缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

具体实现

事件中心具体实现

事件中心传递参数

事件中心传递参数

事件中心传递自定义参数

事件中心传递自定义参数

事件中心的事件名优化

事件中心的事件名优化