位置: 编程技术 - 正文

在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信

编辑:rootadmin
在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学院,致力于打造业内unity3d培训、学习第一品牌。 引子在前面两篇文章:我们了解了2D中的Sprite,Animation,RigidBody和Collider,在继续开发游戏的过程中,我们会遇到这样的问题,如何处理GameObject之间的相互调用,比如说在FlappyBird中我们在小鸟撞倒管子的时候,要把这个消息通知给许多GameObject,管子接到这个消息之后需要停止运动,UI接到这个消息要弹出GameOver的字样。接下来,我来讲一下如何合理地解决这个问题。相关源码参考:Flappy Bird的源码。为什么要进行GameObject之间的通讯?在游戏开发中我们经常遇到这样的问题,在游戏中发生了一个事件(event),我们如何把这个时间通知给其他GameObject:比如游戏中发生了爆炸,我们需要在一定范围内的GameObject都感知到这一事件。有的时候,我们希望摄像机以外的物体不要接到我们这一事件的通知。游戏中丰富多彩的世界正是由通信机制构成的。有一种方法是在发生事件的GameObject的Start方法里面把对该事件感兴趣的所有GameObject当作成员变量保存在脚本组件里,那么我们把发生事件的object当作Subject,把对该事件感兴趣的object当作Observer。将Observer作为成员变量存储在Subject中有一下缺点:难以变更,一旦要新增一个Observer就需要更改Subject中的代码如果Observer被销毁了,无法从Subject中移除掉这个成员变量,会发生NullReferernceException。在发生事件时,一个个去invoke不同Observer中的相应handle方法的代码变得冗长繁杂。还好的是,我们可以通过引入观察者模式来解决这个问题,更好的是,C#内置有一个非常棒的事件/委托机制,能让我们非常方便地进行观察者模式的构建。C#中标准的委托类型我们在构建事件/委托机制的时候,首先要定义委托类型,参考在Cocos2d-x中的CCCallback,我先定义了以下三种类型的委托:// 该委托不传任何参数public delegate void CallFunc();// 该委托会传入发生事件的GameObject,即senderpublic delegate void CallFuncO(GameObject sender);// 该委托会传入发生事件的GameObject,即sender。和一个变长参数列表public delegate void CallFuncOP(GameObject sender, EventArgs args);但是我发现C#本身已经提供了一种比较好的委托类型:EventHandler,所以我就把游戏中的委托都替换成了这种委托。public delegate void EventHandler(object sender, EventArgs e);另一种更好的委托方式是使用泛型参数的委托类型:EventHandlerTEventArgs,其签名如下:public delegate void EventHandlerTEventArgs(Object sender,TEventArgs e) 采用 EventHandler 模式发布事件如果这个事件不产生任何额外参数(即除了事件的发送者之外),则在在调用时,向EventHandler的第二个参数传一个EventArgs.Empty即可。如果产生额外参数,第二个参数是从 EventArgs 派生的类型并提供所有字段或属性需要保存事件数据。使用 EventHandlerTEventArgs 的优点在于,如果事件生成事件数据,则无需编写自己的自定义委托代码。下面我们举一个例子来证实EventHandler的用法:using System;namespace ConsoleApplication1{class Program{static void Main(string[]args){Counter c = new Counter(new Random().Next());//向该事件添加了一个委托函数c.ThresholdReached &#;= c_ThresholdReached;Console.WriteLine("press 'a' key to increase total");while (Console.ReadKey(true).KeyChar == 'a'){Console.WriteLine("adding one");c.Add(1);}}static void c_ThresholdReached(object sender, ThresholdReachedEventArgs e){Console.WriteLine("The threshold of {0} was reached at {1}.", e.Threshold, e.TimeReached);Environment.Exit(0);}}class Counter{private int threshold;private int total;public Counter(int passedThreshold){threshold = passedThreshold;}public void Add(int x){total &#;= x;if (total = threshold){ThresholdReachedEventArgs args = new ThresholdReachedEventArgs();args.Threshold = threshold;args.TimeReached = DateTime.Now;OnThresholdReached(args);}}protected virtual void OnThresholdReached(ThresholdReachedEventArgs e){EventHandlerThresholdReachedEventArgs handler = ThresholdReached;if (handler != null){handler(this, e);}}//添加了一个带泛型参数的事件public event EventHandlerThresholdReachedEventArgs ThresholdReached;}public class ThresholdReachedEventArgs : EventArgs{public int Threshold { get; set; }public DateTime TimeReached { get; set; }}}在游戏中的应用我们通过一个小鸟撞倒管子来作为事例说明如何进行通信:在这个情景下,我们首先为小鸟设定两个事件(event),分别是分数加一(ScoreAdd)和小鸟碰到管子游戏结束(GameOver) 如下:using UnityEngine;using System.Collections;using System;public class BirdController : MonoBehaviour {public event EventHandler GameOver;public event EventHandler ScoreAdd;//当离开Empty Trigger的时候,分发ScoreAdd事件void OnTriggerExit2D(Collider2D col) {if (col.gameObject.name.Equals("empty")) {if (ScoreAdd != null)ScoreAdd(this, EventArgs.Empty);}}//当开始碰撞的时候,分发GameOver事件void OnCollisionEnter2D(Collision2D col){rigidbody2D.velocity = new Vector2(0, 0);if (GameOver != null)GameOver(this, EventArgs.Empty);this.enabled = false;}}然后在对这个事件感兴趣的GameObject会通过相应的Handler对该事件进行监听,这样就可以进行一对多的GameObject间的通信了。using UnityEngine;using System.Collections;using System;public class TubeController : MonoBehaviour {// Use this for initializationvoid Start () {GameObject.Find("bird").GetComponentBirdController().GameOver &#;= OnGameOver;}void OnDestroy() {if ( GameObject.Find("bird") )GameObject.Find("bird").GetComponentBirdController().GameOver -= OnGameOver;}void OnGameOver(object sender, EventArgs e){rigidbody2D.velocity = new Vector2(0, 0);}}

推荐整理分享在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信,希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:,内容如对您有帮助,希望把文章链接给更多的朋友!

在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信

更多内容,请访问【狗刨学习网】unity极致学院

【Unity3D插件】在Unity中读写文件数据:LitJSON快速教程 欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学

通过制作Flappy Bird了解Native 2D中的Sprite,Animation 欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学

通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D 欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学

标签: 在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信

本文链接地址:https://www.jiuchutong.com/biancheng/381513.html 转载请保留说明!

上一篇:unity游戏开发之相关的注意事项及技巧(unity5.x游戏开发指南)

下一篇:【Unity3D插件】在Unity中读写文件数据:LitJSON快速教程(unity 3d插件)

  • 补贴收入如何入账
  • 小规模零申报增值税
  • 农业生产者销售自产农产品按9%的税率征收增值税
  • 独立核算的优点
  • 收购公司财务怎么交接
  • 房地产股权收购案例
  • 从业人数和资产的关系
  • 企业赠送礼品是否涉税
  • 购入资产的入账价格一般是以该项资产的什么反应
  • 已认证进项发票转出会计分录
  • 公司支票可以存到个人账户吗
  • 一般纳税人税负率一般控制在多少?法律依据
  • 用于集体福利的消费税
  • 固定资产附加的账务处理
  • 向一般纳税人销售劳保专用物品
  • 税务稽查补缴的税款怎么处理
  • 公司如何向税务部门举报
  • 忘记申报印花税,但是公司已经注销了怎么办
  • 剪头开发票
  • 金税盘清卡晚了一天会怎么样
  • 方案讲解:关于员工激励的税收筹划
  • 未抵扣的进项税在资产负债表里怎么填
  • 发放活动奖金支出怎么入账
  • 必要报酬率的计算公式Rm
  • 产品毛利率计算表
  • 三金一费包括哪些
  • 外汇局网上申报
  • Linux系统怎么调整屏幕亮度
  • windows伪装电脑mac
  • 华为手机定位另外一个华为手机怎么办
  • 公益性捐赠所得税税前扣除标准
  • 办公费定义
  • 公司个人垫付的费用会计分录
  • 固定资产入账价值计算公式
  • 关联企业承担什么责任
  • linux的vi编辑器怎么用
  • 委托外单位加工发出的材料会影响账面价值吗
  • Micheldever Wood的蓝铃花,英国汉普郡 (© Hursley/Getty Images Plus)
  • 房产税是什么意思,简单的回答
  • 存货短缺会计处理
  • Drömling湿地中的灰鹤,德国 (© Mike Friedrichs/Getty Images)
  • smb命令执行
  • php数组排列组合算法
  • ftpd命令
  • 年报中的利润表本月数需要填吗
  • 用于职工福利的固定资产折旧
  • 自然人个税申报密码怎么获取
  • 纳税收入包括居民个人在境外取得的收入吗?
  • 下列项目的进项税额可以从销售税额中抵扣的是
  • 个人缴纳税是什么意思
  • 已抵扣认证的发票开红字发票需要将原票退回吗
  • 营改增后建筑企业税负
  • 未计提坏账准备金额在哪个表
  • 个贷系统平账专户怎么做账
  • 实际费用以什么为准
  • 施工企业会计成本费用论文3000字
  • 影响以前年度损益的科目
  • 一般纳税人拿到普票怎么处理账务
  • 一般纳税人弱电包工包料怎么开票
  • 某项租赁合同,租赁期为8年,每年年末支付租金100万
  • 会计做内账的技巧与方法
  • 选择业务组合的原则是什么
  • sql-3
  • mysql 5.7.28安装
  • cmd命令行窗口快捷键
  • linux中chkconfig命令的作用
  • xp开始菜单没反应
  • xp系统开机只有一个鼠标箭头
  • centos重启动停在4m
  • centos6可用yum源
  • win7系统的分区类型怎么选
  • 电脑w7系统怎么保存图片
  • nodejs爬虫框架crawler
  • 批处理生成excel
  • [置顶]bilinovel
  • 爬虫如何识别验证码
  • python爬取新浪股票数据
  • 内蒙古税务局电子发票查询
  • 如何在河南省社会保障网上平台进行社保基数申报
  • 发票勾选后必须抵扣吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设