Unity开发之观察者模式(事件中心)

news2025/1/11 0:46:47

观察者模式是一种对象行为模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。在观察者模式中,主体是通知的发布者,它发出通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。

一、事件中心管理类

继承了一个单例模式基类,节省代码

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

此时按下鼠标左键五次,可以看到触发了提示但是因为杀的不是哥布林,所以任务没有完成

 将名字改为哥布林,点击三次后提示完成任务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1128408.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

随机森林算法(Random Forest)的二分类问题

二分类问题 1. 数据导入2. RF模型构建2.1 调参&#xff1a;mtry和ntree2.2 运行模型 3. 模型测试4.绘制混淆矩阵5.绘制ROC曲线6. 参考 1. 数据导入 library(dplyr) #数据处理使用 library(data.table) #数据读取使用 library(randomForest) #RF模型使用 library(caret) # 调参…

软件测试之 测试用例 如何设计

在软件开发过程中&#xff0c;测试是一个至关重要的环节&#xff0c;它有助于确保软件的质量和稳定性。而测试用例设计则是测试过程中的一个关键步骤&#xff0c;它帮助测试团队确定如何测试软件以发现潜在的问题和缺陷。本文将介绍测试用例设计的基本概念和步骤&#xff0c;以…

产品研发团队协作神器!10款提效工具大盘点!

在如今科技驱动的时代&#xff0c;产品研发团队面临着前所未有的竞争压力和不断变化的市场需求。为了在这个激烈的环境中脱颖而出&#xff0c;团队需要高效协作并充分利用先进的工具来提高生产力和创新能力。 本文将为你盘点产品研发团队协作必备的10个提效工具&#xff0c;这…

TiDB、MySQL与Oracle的char字段

文章目录 MySQLTiDBOracle结论 我们组在团队内维护了一套TiDB&#xff0c;有时候会有其他同事来请教一些问题&#xff0c;当然遇到比较复杂的问题&#xff0c;我也会直接抛给DBA。今天有个同事来问了一下TiDB的char字段查询是否需要补空格。在我的印象中&#xff0c;TiDB是高度…

【Docker】Docker学习之一:离线安装Docker步骤

前言&#xff1a;基于Ubuntu Jammy 22.04 (LTS)版本安装和测试 1、Docker安装 1.1、离线安装 步骤一&#xff1a;官网下载 docker 安装包 wget https://download.docker.com/linux/static/stable/x86_64/docker-24.0.6.tgz步骤二&#xff1a;解压安装包; tar -zxvf docker…

安防监控视频汇聚平台EasyCVR增加AI算法列表接口的实现方法

安防监控视频汇聚平台EasyCVR基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;可提供视频监控直播、云端录像、云存储、录像检索与回看、智能告警、平台级联、云台控制、语音对讲、智能分析等功能。平台既具备传统安防监控的能力&#xff0c;也…

C++进阶语法之函数和指针【学习笔记(三)】

文章目录 1、C 函数1.1 函数的定义1.2 函数原型&#xff08;function prototypes&#xff09;1.3 参数&#xff08;parameter&#xff09;——值传递&#xff08;pass by value&#xff09;1.4 重载&#xff08;overloading&#xff09;1.5 函数传参——传递数组&#xff08;ar…

Linux下控制GPIO的三种方法

https://blog.csdn.net/qq_41076734/article/details/124669908 1. 应用空间控制gpio 1.1简介 在/sys/class/gpio/下有个export文件&#xff0c;向export文件写入要操作的GPIO号&#xff0c;使得该GPIO的操作接口从内核空间暴露到用户空间&#xff0c;GPIO的操作接口包括dir…

Flink学习笔记(四):Flink 四大基石之 Window 和 Time

文章目录 1、 概述2、 Flink 的 Window 和 Time2.1、Window API2.1.1、WindowAssigner2.1.2、Trigger2.1.3、Evictor 2.2、窗口类型2.2.1、Tumbling Windows2.2.2、Sliding Windows2.2.3、Session Windows2.2.4、Global Windows 2.3、Time 时间语义2.4、乱序和延迟数据处理2.5、…

linux系统安装Googletest单元测试框架

环境信息 系统&#xff1a;ubuntn cmake版本&#xff1a;3.5.1 gcc版本&#xff1a;5.4.0 1、下载googletest git clone https://github.com/google/googletest.git注意&#xff01;不选branch的话默认下载最新版本&#xff08;需要编译器能够支持C14&#xff09;&#xff0c;…

如何生成osg的动画路径文件

目录 1. 前言 2. 生成动画路径文件 2.1. 粗糙方式 2.2. 精确方式 1. 前言 在进行osg的开发中&#xff0c;有时需要对模型按某个路径或规则进行动画&#xff0c;如下&#xff1a; 奶牛在10秒时间段从起始的osg::Vec3d(0.0, 18, 1.0)位置 匀速直线运动到osg::Vec3d(0.0, -8, …

ubuntu 中使用Qt连接MMSQl,报错libqsqlodbc.so: undefined symbol: SQLAllocHandle

Qt4.8.7的源码编译出来的libqsqlodbc.so&#xff0c;在使用时报错libqsqlodbc.so: undefined symbol: SQLAllocHandle&#xff0c;需要在编译libqsqlodbc.so 的项目pro文件加上LIBS -L/usr/local/lib -lodbc。 这里的路径根据自己的实际情况填写。 编辑&#xff1a; 使用uni…

Python数据结构(队列)

Python数据结构&#xff08;队列&#xff09; 队列(queue)是只允许在一端进行插入操作&#xff0c;而在另一端进行删除操作的线性表。 队列是一种先进先出的 (First n First ut)的线性表&#xff0c;简称FIFO。允许插入的一端为队尾&#xff0c;允许删除的一端为队头&#xff…

深度学习——图像分类(CIFAR-10)

深度学习——图像分类&#xff08;CIFAR-10&#xff09; 文章目录 前言一、实现图像分类1.1. 获取并组织数据集1.2. 划分训练集、验证集1.3. 图像增广1.4. 引入数据集1.5. 定义模型1.6. 定义训练函数1.7. 训练模型并保存模型参数 二、生成一个桌面小程序2.1. 使用QT设计师设计界…

建筑工程模板分类以及特点?

建筑工程模板可以根据材料、结构和用途等方面进行分类。以下是一些常见的建筑工程模板分类及其特点&#xff1a; 1. 木质模板&#xff1a; - 特点&#xff1a;木质模板是最常见和传统的模板类型。它们由木材制成&#xff0c;具有良好的可塑性和可加工性。木质模板适用于各种形状…

京东数据分析:2023年9月京东白酒行业品牌销售排行榜

鲸参谋监测的京东平台9月份白酒市场销售数据已出炉&#xff01; 9月白酒市场的整体热度较高&#xff0c;贵州茅台先是与瑞幸联名推出酱香拿铁&#xff0c;后又宣布与德芙推出联名产品酒心巧克力&#xff0c;引起了诸多消费者的关注。在这一热度的加持下&#xff0c;从销售上看&…

Kali Linux 安装搭建 hadoop 平台 调用 wordcount 示例程序 详细教程

步骤一&#xff1a; 目标&#xff1a;*安装虚拟机&#xff0c;在自己虚拟机上完成hadoop的伪分布式安装。&#xff08;安装完成后要检查&#xff09;* 1&#xff09;前期环境准备&#xff1a;&#xff08;虚拟机、jdk、ssh&#xff09; 2&#xff09;SSH相关配置 安装SSH Se…

【MyBatis篇】MyBatis动态代理总结

本人正在浅学mybatis&#xff0c;正学到mybatis动态代理&#xff0c;在查询多方资料之后做出以下总结&#xff0c;以便于系统学习时回顾&#xff1b; 目录 MyBatis为什么引入动态代理 mybatis的动态代理 Dao代理技术 MyBatis为什么引入动态代理 因为程序员的 懒&#xff0c;…

访问控制2

文章目录 主要内容一.Role和ClusterRole1.ClusterRole示例&#xff0c;创建一个名为test-clusterrole且仅有创建Pod和deployment的集群角色代码如下&#xff08;示例&#xff09;: 2.YAML文件创建代码如下&#xff08;示例&#xff09;: 3.将udbs用户和Clusterrole进行绑定&…

0基础学习VR全景平台篇第112篇:控制点和遮罩工具 - PTGui Pro教程

上课&#xff01;全体起立~ 大家好&#xff0c;欢迎观看蛙色官方系列全景摄影课程&#xff01; 前情回顾&#xff1a;上节&#xff0c;我们用PTGui拼接了一张全景图&#xff0c;全景编辑器里的各项功能帮助我们进行了初步的检查和编辑。 之后我们需要使用【控制点】和【遮罩…