赞
踩
观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在观察者模式中,主体是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。
一、事件中心管理类
继承了一个单例模式基类,节省代码
- public class EventCenter : BaseManager<EventCenter>
- {
- //key —— 事件的名字(比如:怪物死亡,玩家死亡,通关 等等)
- //value —— 对应的是 监听这个事件 对应的委托函数们
- private Dictionary<string, UnityAction<object>> eventDic = new Dictionary<string, UnityAction<object>>();
-
- /// <summary>
- /// 添加事件监听
- /// </summary>
- /// <param name="name">事件的名字</param>
- /// <param name="action">准备用来处理事件 的委托函数</param>
- public void AddEventListener(string name, UnityAction<object> action)
- {
- //有没有对应的事件监听
- //有的情况
- if( eventDic.ContainsKey(name) )
- {
- eventDic[name]+= action;
- }
- //没有的情况
- else
- {
- eventDic.Add(name, action);
- }
- }
-
- /// <summary>
- /// 过场景,移除对应的事件监听
- /// </summary>
- /// <param name="name">事件的名字</param>
- /// <param name="action">对应之前添加的委托函数</param>
- public void RemoveEventListener(string name, UnityAction<object> action)
- {
- if (eventDic.ContainsKey(name))
- eventDic[name]-= action;
- }
-
- /// <summary>
- /// 事件触发
- /// </summary>
- /// <param name="name"></param>
- public void EventTrigger(string name,object info)
- {
- //有没有对应的事件监听
- //有的情况
- if (eventDic.ContainsKey(name))
- {
- if (eventDic[name]!= null)
- eventDic[name].Invoke(info);
- }
- }
-
- /// <summary>
- /// 清空事件中心
- /// 主要用在 场景切换时
- /// </summary>
- public void Clear()
- {
- eventDic.Clear();
- }
- }

二、模拟一个功能
玩家要完成一个任务“杀死三只哥布林”,玩家点击鼠标左键杀死一只怪物,如果这个怪物是哥布林,那么任务计数加1,达到3后提示任务完成。
其中还会显示玩家击杀了什么怪物,击杀后获得多少金钱
玩家类
- public class Player : MonoBehaviour
- {
- public string name = "Holens";
- // Start is called before the first frame update
- void Start()
- {
- EventCenter.GetInstance().AddEventListener("MonsterDead", GetMoney);
- }
-
- // Update is called once per frame
- void Update()
- {
- //按下左键杀死哥布林
- if (Input.GetMouseButtonDown(0))
- {
- KillMonster();
- }
- }
-
- public void KillMonster()
- {
- //杀死哥布林
- //向事件中心发送请求 执行杀死哥布林逻辑
- EventCenter.GetInstance().EventTrigger("KillMonster", this);
- }
- public void GetMoney(object info)
- {
- print(this.name+"杀死了" + (info as Monster).name + "获得"+ (info as Monster).money+"金钱");
- }
- }

怪物类
- public class Monster : MonoBehaviour
- {
- public string name;
- public int money = 100;
- // Start is called before the first frame update
- void Start()
- {
- //向 击杀哥布林 委托添加死亡函数
- EventCenter.GetInstance().AddEventListener("KillMonster", Dead);
- }
-
- public void Dead(object info)
- {
- print((info as Player).name+"杀死了"+this.name);
- //死亡时向事件中心发送请求 执行怪物死亡逻辑
- EventCenter.GetInstance().EventTrigger("MonsterDead", this);
- }
- }

任务类
- public class Task : MonoBehaviour
- {
- public int nowNum;
- public int maxNum = 3;
- public string messionInfo = "杀死三只哥布林";
- public bool isFinish = false;
- // Start is called before the first frame update
- void Start()
- {
- print("任务目标是" + messionInfo);
- //怪物死亡
- //向 怪物死亡 委托添加函数(当怪物死亡时任务计数加1)
- EventCenter.GetInstance().AddEventListener("MonsterDead", UpdateNum);
- }
-
- // Update is called once per frame
- void Update()
- {
- if (nowNum == maxNum&&!isFinish)
- {
- //计数达到目标,任务完成
- FinishMession();
- isFinish = true;
- }
- }
- public void UpdateNum(object info)
- {
- //如果杀死的目标是哥布林,则计数增加
- if ((info as Monster).name=="哥布林")
- {
- nowNum++;
- }
- }
- public void FinishMession()
- {
- print("任务完成");
- }
- }

三、运行过程及结果
创建三个物体并挂载相应代码
怪物名字设置成1
此时按下鼠标左键五次,可以看到触发了提示但是因为杀的不是哥布林,所以任务没有完成
将名字改为哥布林,点击三次后提示完成任务
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。