位置: 编程技术 - 正文

事件委托机制实现GameObject之间的通信(事件委托实现)

编辑:rootadmin
欢迎来到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# 中的委托和事件 -- 委托/事件入门  C#综合揭秘深入分析委托与事件 -- 委托/事件深入  你可能不知道的陷阱:C#委托和事件的困惑 -- 委托/事件陷阱  C#中标准的委托类型  我们在构建事件/委托机制的时候,首先要定义委托类型,参考在Cocos2d-x中的CCCallback,我先定义了以下三种类型的委托:  // 该委托不传任何参数  public delegate void CallFunc();  // 该委托会传入发生事件的GameObject,即sender  public 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 initialization  void 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极致学院 声明:此篇文档时来自于【狗刨学习网】社区-unity极致学院,是网友自行发布的Unity3D学习文章,如果有什么内容侵犯了你的相关权益,请与官方沟通,我们会即时处理。

推荐整理分享事件委托机制实现GameObject之间的通信(事件委托实现),希望有所帮助,仅作参考,欢迎阅读内容。

事件委托机制实现GameObject之间的通信(事件委托实现)

文章相关热门搜索词:事件委托的原理以及优缺点,事件委托的实现思路,事件委托实现,事件委托jq,事件委托jq,事件委托机制将事件绑定到哪,事件委托机制的原理,事件委托机制实例,内容如对您有帮助,希望把文章链接给更多的朋友!

Unity AssetBundle爬坑手记 欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学

Unity3D 事件 欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学

unity动态加载之AssetBundle原理 Assetbundle是UnityPro提供提供的功能,它可以把多个游戏对象或者资源二进制文件封装到Assetbundle中,提供了封装与解包的方法使用起来很便利。1.预设Assetb

标签: 事件委托实现

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

上一篇:使用unity3d需要注意到细节(unity3d需要购买吗)

下一篇:Unity AssetBundle爬坑手记

  • 发票多开了,要求退回重开,如何处理
  • 外籍人员可以在中国工作吗
  • 金税四期的主要功能
  • 其他应收款增加银行存款减少的原因
  • 开普票的销项税额
  • 可辨认净资产和所有者权益的区别
  • 财务费用余额方向怎么填
  • 退休职工怎么填写单位吗
  • etc充值怎么操作
  • 客运承运人是什么意思
  • 房产税的计税依据有哪些
  • 工程总包如何开具发票和征税
  • 银行卡待报解预算收入是什么钱
  • 在建工程完工结转
  • 收到投资者购买股票的资金
  • 电子承兑汇票没开通能接受吗
  • 居民企业技术转让所得税优惠政策
  • 企业转让股权取得的收入征税吗
  • 私立医院增值税税率是多少
  • 旧税号的发票专用章还能使用吗
  • 2017年广告费税率
  • 长期待摊费用涉税风险应对
  • 成本控制的基本原则包括
  • 个人独资企业的特点
  • "专项储备"在合并报表层面如何处理?
  • 已经认证的发票怎么冲红
  • applepay怎么用云闪付
  • 怎样获得win11
  • 怎么样防止蹭wi-fi
  • php string函数
  • 拍卖获得收入个税
  • 路由器的默认网关在哪里看
  • 双线服务器
  • 会计分录的基本构成要素
  • 最贵的游戏宣传片
  • php访问数据库的一般步骤
  • 前端开发软件哪个最好
  • php接口技术实例分析
  • 其他收益会计科目怎么写
  • 深度学习中正样本、负样本、简单样本、困难样本的区别 (简单易懂)
  • linux中login命令
  • 命令行延时
  • 以前年度损益调整会计分录
  • 自有资金等于货币资金吗
  • 出口退税单机版是什么意思
  • 商品流通企业的含义
  • 积分兑换业务有风险吗
  • 下列项目的进项税额可以从销售税额中抵扣的是
  • 对方发票丢了能红冲重开吗
  • mysql proxy问题的解决方法
  • 生产成本帐
  • 一般纳税人的商业保险可以开票吗
  • 金税四期对企业的影响与应对
  • 小规模纳税人免税政策2023年
  • 借应付职工薪酬贷财政拨款收入
  • 私车公用必须是公司员工的车吗?
  • 企业优惠政策是什么意思
  • 借长期借款贷在建工程
  • 滞留票不处理可以么
  • 公司为员工购买汽车怎么申报
  • 哪些福利费没有附加税
  • mysql常见语句总结
  • sql server字符串函数
  • mysql怎么清理干净
  • wrme.exe是什么
  • Win10系统如何开启全部权限
  • 如何设置win10自动登录
  • win2008个性化
  • Windows XP Professional VLK SP2 简体中文版
  • centos 操作
  • linux012
  • cocos2dx tableview基础:实现多图片的滑动显示
  • exec方法
  • android mark
  • awk实例
  • jquery获取document对象
  • linux重启关闭打开达梦数据库
  • node.js上传文件
  • 快速进入屏保的快捷键
  • 增值税税控系统专用设备及技术维护费
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设