Unity—事件

news/2024/12/2 14:04:18/

每日一句:我见青山多妩媚,料青山见我应如是

目录

事件

委托和事件的关系?

为什么使用委托类型来声明事件?/为什么事件是基于委托的?

事件的定义

事件的核心功能

事件和事件模型

如何自定义事件


事件

委托和事件的关系?

事件是委托类型字段的包装器、限制器,限制外界对委托类型字段的访问,委托类型字段通过事件包装、限制后,外界只能去访问它的+=、-=操作符(添加/移除事件处理器)

为什么使用委托类型来声明事件?/为什么事件是基于委托的?

【事件拥有者角度】

为了表明事件拥有者能够对外部通知什么样的消息

【事件响应者角度】

一种[约束]事件处理器,能够收到什么样的消息

也约束了我们使用什么方法、签名来处理相应这个事件

并且会去使用委托类型的实例去储存方法的引用,去储存 事件处理器

事件响应者事件拥有者,提供了与之匹配的事件的事件处理器,能够记录、引用方法的这个任务,只有委托类型的实例才能做到

【Event事件是基于委托delegate】

  1. 类型兼容

事件响应者的事件处理器必须和这个约束匹配上,才能够订阅这个事件

  1. 通过委托去存储方法

记录、存储、保存方法的任务,委托类型实例才能办到

事件无论从表层约束上来说,还是底层实现上来讲,都依赖于委托类型

事件的定义

事件使一个类或者对象去通知其他类,对象们

事件是一个类型成员

事件可以“发生”,通知别人,发生后的效果,才是事件的功能

事件的核心功能

就是将事件的事件参数,也就是事件的相关信息,通知给那些订阅了这个事件的人们

“XX对象拥有了某个事件”或“X类它含有一个事件”——>这个类对象可以通过这个事件,来通知别的对象。如果这个事件发生了,关心、订阅这个事件的其他对象们会被依次的通知到,并且,它们会纷纷的做出响应,这些对象们就会协调统一的工作起来,程序,也会因为这个事件而发生变化

事件和事件模型

五个步骤:

  1. 我(类)要有一个事件(成员)
  2. 一群别的类关心,订阅我的事件
  3. 我的事件发生了
  4. 关心的类们被一次性通知到
  5. 被通知到的人,拿着事件参数作出响应

五个组成部分

事件的拥有者 事件的源头,一定是个类(或者对象)

事件  成员类型,核心功能:通知其他类,对象作出响应。事件不会主动发生,一定是由事件拥有者的内部逻辑触发

事件的响应者

事件处理器 处理事件的方法成员

事件订阅(+=操作符)

订阅关系+=

  1. 事件发生后,通知的一定是[订阅]了事件的对象们
  2. 事件处理器和事件的关系(本质就是事件处理器的返回值和参表是否和事件的委托类型一致)[C#规定:用于订阅事件的这个事件处理器,必须和事件遵循同一个约定,已经定义好的事件内部都有委托类型]
  3. 具体哪个事件处理器,处理那个事件

(因为一个事件响应者,可能有很多个满足约定的事件处理器)

例子:功能:每N秒进行一个固定的行为功能(打印信息)

//事件的拥有者:timer

//事件:E lapsed

//事件的响应者:Printer

//事件处理器:MyAction(自定义一个方法)

//事件的订阅关系:+=

public class EventEx:MonoBehaviour

{ Timer timer=new Timer();

  private void Start()

{ timer.Elapsed+=Printer.MyAction;}//添加事件处理器的简化写法

 【{timer.Elapsed+=new ElapsedEventHandle(委托类型)(Printer.MyAction)}//使用事件处理器,初始化一个新的委托实例】

{事件的拥有者.事件+=事件的响应者.事件处理器}

//Printer类的事件处理器:MyAction订阅了由timer为主体的[Elapsed事件]

public class Printer

{ internal static void MyAction(object sender,ElapsedEventAvags e)

{ Debug.Log(aaa);}

}

如何自定义事件

.Net规定,如果这个委托是为了声明某个事件而准备的,这个委托的命名方式

事件名+EventHandler

事件不能在外部直接调用,只有事件的拥有者通过某些内部逻辑才能触发

事件的拥有者【类】Customer类

事件【event关键字修饰】OnOrder事件

事件的响应者【类】Waiter事件

事件处理器【方法_受到约束的方法】TakeAction方法

事件的订阅关系【+=】

public delegate void OrderEventHandler(Customer _customer,OrderEventArgs _e)//为了声明OrOrder事件所使用

public class EventEx:MonoBehaviour

{ Customer customer =new Customer();

  Waiter waiter =new Waiter();

  private void Start()

{customer.OnOrder+=waiter.TakeAction;}

//事件拥有者的事件成员+=事件响应者的事件处理器(来订阅OnOrder事件)

//事件拥有者的内部逻辑触发的事件

customer.Order();

customer.PayTheBill();

}

public class Customer

{ public float Bill{get;set;}

public void PayTheBill()

{Debug.Log(I have to pay:+this.Bill);}

private  OrderEventHandler  orderEvenHandler;

//声明委托类型的字段,将会去存储,引用副委员的事件处理器

public evnet OrderEventHandler OnOrder//事件声明完整格式

{ add

   {orderEventHandler+=value;}

//委托事件+=事件处理器

remove

{orderEventHandler-=value;}

}

public event OrderEventHandler OnOrder;//事件声明简略格式

public void Order()//内部逻辑

{ if(orderEventHandler!=null)

{ orderEventArgs e=new OrderEventArgs();

 e.CoffeeName=Mocha;

 e.CoffeeSize=Tall;

 e.CoffeePrice=28;

 OrderEventHandler(this,e);

}

}

public class OrderEventArgs:EventArgs//存储点餐信息 传递事件参数

{   public string CoffeeName{get;set;}

public string CoffeeSize{get;set;}

public string CoffeePrice{get;set;}

}

}

}

public class Waiter

{ internal void TakeAction(Customer _customer,OrderEvnetArgs _e)

//根据顾客点餐信息传递事件参数计算不同金额

{ flaot finalPrice=0;

 switch(_e.CoffeeSize)

 { caseTall:

finalPrice=_e.CoffeePrice;

break;

caseGrand:

finalPrice=_e.CoffeePrice+3;

break;

caseVenti:

finalPrice=_e.CoffeePrice+6;

break

      }

_custome.Bill+=finalPrice;

}

}

属性是字段的包装器

事件是委托类型字段的包装器

字段能做到的属性都能做;属性能做的,字段不一定都能做

is操作符:检查对象是否与给定的类型兼容

as操作符:用于检查在兼容的引用类型之间执行某些类型的转换

//以上内容听B站宝藏Up主—BeaverJoe的课,做的学习笔记


http://www.ppmy.cn/news/11908.html

相关文章

基于FPGA的UDP 通信(四)

引言 前文链接: 基于FPGA的UDP 通信(一) 基于FPGA的UDP 通信(二) 基于FPGA的UDP 通信(三) 本文基于FPGA与MATLAB作千兆以太网通信模块UDP数据接收实验板级验证:FPGA接收上位机数…

List subList()方法缺陷及替代方案

技术背景 在日常开发中&#xff0c;我们常遇到将一个List列表分割成多个的场景&#xff0c;List提供了subList()方法避免开发者重复造轮子。 subList()的用法 ArrayList类是接口List的一个实现&#xff0c;以下subList()使用方法参考示例来自ArrayList。 List<String>…

向“全栈”进发,大型线上商城实战项目,Spring Boot + Vue 前后端分离版本的商城来了(文末有视频)

新蜂商城 Vue 版本&#xff0c;它来了&#xff01;&#xff08;文末有视频&#xff09; 如上图所示&#xff0c;新蜂商城 Vue 版本已经开发完成&#xff0c;这是新蜂商城开源项目的第一个大版本更新&#xff0c;根据大量的用户调研&#xff0c;最终决定将新蜂商城升级为 Spring…

MyBatis获取参数值的两种方式

MyBatis获取参数值的两种方式在idea中设置模板MyBatis获取参数值的两种方式mapper接口方法的参数为单个字面量类型mapper接口方法的参数为多个时自动存入map手动存入mapmapper接口方法的参数是实体类类型的参数使用Param注解命名参数为什么这么多方法却说是两种方式&#xff1f…

Unity 2d碰撞检测

碰撞检测Collider2d 射线检测函数Raycast 与 Cast 函数Overlap 检测函数参数PhysicsScene2D 类检测函数Physics2D 类检测函数MonoBehaviour 类碰撞检测函数Collider2d 射线检测函数 Raycast 与 Cast 函数 Raycast 是发射一条射线 Cast 是把整个碰撞器作为射线投射出去 enabl…

适应性学习率

目录 适应性学习率 Adaptive learning rate 为什么不是临界点仍会导致训练停止 示例一示例二 RMSRMSPropAdam学习率还和时间有关 Learin Rate DecayWarm up 2021 - 类神经网络训练不起来怎么办(三) 自动调整学习率 (Learning Rate)适应性学习率 Adaptive learning rate 一般…

ASP.NET Core 3.1系列(26)——Autofac中的实例生命周期

1、前言 前面的博客主要介绍了Autofac中的一些注册方法&#xff0c;下面就来介绍一下Autofac中实例的生命周期。之前在介绍ASP.NET Core内置IoC容器的时候说过&#xff0c;实例的生命周期有&#xff1a;瞬时生命周期、域生命周期、全局单例生命周期&#xff0c;而Autofac在这三…

【5】K8S_Deployment

目录 1、Deployment作用 2、deployment的冗余能力 3、deployment的多副本部署 4、deployment的扩缩容 5、deployment的自愈能力 6、滚动更新 7、版本回退 1、Deployment作用 控制Pod&#xff0c;使Pod拥有多副本&#xff0c;自愈&#xff0c;扩缩容等能力 2、deployme…