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

硬件开发笔记(十三):RK3568底板HDMI2.0接口信号完整性设计与PCB布线实战解析 本文详细解析了RK3568底板HDMI2.0接口的信号完整性设计与PCB布线实战经验。从差分信号阻抗控制、等长匹配时序优化到参考平面与EMC设计,提供了全面的技术指导。通过实际案例分享,帮助硬件工程师规避常见设计陷阱,确保HDMI2.0接口在RK3568平台上的稳定运行,满足4K@60Hz的高带宽传输需求。 阅读详情

  我们了解了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(10));
  //向该事件添加了一个委托函数
  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);
  }
  }




Unity3D技巧在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信 作者:王选易,出处:http://www.cnblogs.com/neverdie/欢迎转载,也请保留这段声明。如果你喜欢这篇文章,请点【推荐】。谢谢! 本文的参考博客:https://blog.youkuaiyun.com/wkkingsam/article/details/52403126 引子 在前面两篇文章: 【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy ... 阅读详情

相关推荐

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

在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信 欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学院,致力于打造业内unity3d培训、学习第一品牌。  引子 在前面两篇文章: 我们了解

2239

UGUI之UI组件及GameObject的事件监听系统封装

     第一种:用代码动态的给组件加监听事件,都是利用组件本身的事件接口去实现相应事件的方法,只不过是用代码实现的动态添加的事件监听。下面是放个按钮的添加监听事件的方法,其中一个是带参数的添加方法。using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Eve...

居安思危,游戏人生。 997

Unity事件机制全解析:从委托到UnityEvent的实战应用

在软件工程中,事件驱动架构是一种实现模块间松耦合通信的核心设计模式。其原理基于发布-订阅模型,允许发布者广播状态变化,而订阅者无需了解发布者细节即可响应。这种模式的技术价值在于显著提升代码的可维护性、可扩展性和可测试性,尤其适用于需要多模块协作的复杂系统。在游戏开发领域,事件机制广泛应用于处理用户输入、角色状态切换、资源加载回调以及成就系统触发等场景。Unity引擎中的事件系统,特别是C#原生事件和UnityEvent,为开发者提供了强大的工具集。通过委托(Delegate)定义方法签名,事件(Event)

weixin_30613343的博客 480

Unity中使用委托/事件实现GameObject之间的通信

Unity中使用委托/事件实现GameObject之间的通信

cuit_xuchen的博客 4975

Unity委托与事件:从C#基础到UnityEvent实战应用

在C#编程中,委托是一种类型安全的函数指针,它允许将方法作为参数传递和存储,是实现回调机制和事件驱动编程的基础。其核心原理是通过定义方法签名来创建委托类型,从而实现方法的间接调用和多播能力。这一机制在软件开发中具有重要价值,能够有效降低模块间的耦合度,提升代码的可维护性和扩展性。在游戏开发领域,尤其是Unity引擎中,委托与事件的应用场景极为广泛,从简单的UI交互到复杂的游戏系统通信都离不开它们。Unity进一步封装了C#的委托机制,提供了UnityAction和UnityEvent等工具,使得开发者能够在

weixin_30367873的博客 563

Unity游戏开发中的委托与事件系统:从原理到实战应用

在C#编程与Unity游戏开发中,委托(Delegate)作为一种类型安全的函数指针,是实现方法封装与传递的核心机制。其原理在于允许将方法作为参数存储和调用,从而在对象间建立松耦合的通信桥梁。这一机制的技术价值在于显著提升代码的可维护性与灵活性,避免了硬编码带来的依赖混乱。在应用场景上,委托广泛用于实现观察者模式、事件驱动架构以及异步回调处理,是构建游戏内交互系统(如UI响应、角色状态切换、资源加载回调)的基础。通过事件(Event)对委托进行封装,可以进一步确保通信的安全性,防止外部非法调用。本文以Uni

soyo的专栏 546

Unity3D中API常用方法和类详细讲解(事件函数、GameObject类、MonoBehaviour 类)

下图是Unity 中各个类的继承关系: 每一个脚本默认都是继承MonoBehaviour的 MonoBehaviour是继承Behaviour的 Behaviour是继承Component的 Component是继承Object的 GameObject 是 继承Object的 事件函数 点击这里进入Unity 官网文档了解更多。 start 方法: 这个方法在游戏场景加...

TAOTAO 2547

c++实现的对象事件驱动机制

实现的事件驱动机制,绑定对象与事件,通过成员方法响应事件,采用c++的方法实现,不依赖于任何平台

unity中,GameObject的长按事件

给物体添加Event Trigger组件 在Event Trigger面板中,点击Add new Event Type,选择Poniter Down && Pointer Up Pointer Down在按下时触发 Pointer Up在抬起时触发,从按下开始记录时间,便可以进行长按事件的触发 //长按时间记录 private float longPressTime; private bool isLongPress; private void Awake.

qq_40666620的博客 1346

从零到一:DAMASK与ABAQUS联合仿真的环境配置艺术

本文详细介绍了在Ubuntu 16.04系统中配置DAMASK与ABAQUS2017联合仿真环境的完整流程,涵盖系统基础环境搭建、Python科学计算环境构建、DAMASK核心安装与配置,以及ABAQUS集成与联合调试。通过实战案例和高级调试技巧,帮助用户快速掌握有限元分析中的晶体塑性模拟技术。

weixin_29253711的博客 857

从零到一:STM32CubeMX虚拟串口开发中的常见陷阱与优化策略

本文深入探讨了STM32CubeMX在USB虚拟串口开发中的常见问题与优化策略,涵盖数据流吞吐量瓶颈、实时性约束等核心挑战。通过实战案例和代码示例,详细解析了波特率同步异常、数据丢失等问题的解决方案,并提供了DMA配置和中断优先级调优的高级技巧,帮助开发者提升STM32虚拟串口的性能和可靠性。

weixin_29164185的博客 370

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

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明。如果你喜欢这篇文章,请点【推荐】。谢谢! 引子 在前面两篇文章: 【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D 【Unity3D基础教程】给初学者看的Un...

weixin_30544657的博客 732

STM32的DMA模块及Protues仿真实验

(一)DMA简介      DMA(Direct Memory Access,直接存储器访问), 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可 供其它操作使用。      STM32F407共有两个 DMA 控制器,总共有 16 个数据流(每个控制器 8 个),每一个 DMA 控制器都用于管理 一个或多

weixin_45930204的博客 2849

unity 3d 使用C#的事件/委托机制

转自:http://blog.youkuaiyun.com/hiramtan/article/details/8955472 事件分发: using UnityEngine; public class EventDispatcher : MonoBehaviour { public delegate void EventHandler(GameObject e); public

随缘,随心 820

数学建模:相关性分析学习——皮尔逊(pearson)相关系数与斯皮尔曼(spearman)相关系数

相关性分析:求解相关系数并绘制热力图进行对比

weixin_67565775的博客 8万+

启动盘安装Win10完整指南:U盘制作、BIOS设置与分区排错

系统重装是解决电脑卡顿、系统崩溃、病毒残留等问题的基础操作,而U盘启动盘则是目前最主流的安装介质。其核心原理在于通过Rufus等工具,将原版ISO镜像写入U盘,并依据主板固件类型(UEFI或Legacy)选择对应的GPT或MBR分区表,确保引导程序能正确加载。掌握这些底层概念,不仅能提升安装成功率,还能避免因引导模式不匹配导致的黑屏、无法启动等问题。在实际应用中,无论是老旧电脑升级、硬盘更换,还是需要纯净的系统环境,制作一个可靠的启动盘都是必备技能。本文从备份数据、下载官方镜像讲起,逐步演示U盘制作、启动快

weixin_32667955的博客 339

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

欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D培训视频、U3D教程、U3D常见问题、U3D项目源码,【狗刨学习网】unity极致学院,致力于打造业内unity3d培训、学习第一品牌。   一对多的观察者模式机制有什么缺点?      如果你对如何在Unity中使用事件/委托机制还不太了解,建议您查看我的前一篇文章:【Unity3D

3076

103.在 Vue 3 中使用 OpenLayers 控制图层来显示/隐藏地图

是一个强大的开源库,可以用于构建各种地理信息系统应用。在 Vue 3 中,我们可以结合。方法,可以直接控制某个图层是否可见,而不需要删除或重新创建图层。在开始之前,确保你已经搭建了 Vue 3 项目,并安装了。本文将详细介绍如何在 Vue 3 组合式 API (,并实现按钮控制地图的显示/隐藏功能。会导致 OSM 瓦片地图无法加载。方法控制地图图层的显示与隐藏。安装完成后,即可开始编写代码。在本教程中,我们介绍了如何在。来实现地图的显示/隐藏功能。来实现交互式地图,并通过。在 WebGIS 开发中,

小彭的博客 1560

【Unity3D技巧】在Unity中使用事件/委托机制

引子在前面两篇文章:【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D【Unity3D基础教程】给初学者看的Unity教程(三):通过制作Flappy Bird了解Native 2D中的Sprite,Animation我们了解了2D中的Sprite,Animation,RigidBody和...

kenljh的博客 2454

手把手实现STM32+ESP8266+原子云服务器+手机APP应用——第三节-编写STM32程序实现STM32+ESP8266+原子云服务器+手机APP互相通信—远程数据传输及控制灯

接上一篇,本节使用原子云服务器。编写STM32程序实现STM32+ESP8266+原子云服务器+手机APP互相通信—远程数据传输及控制灯。使用的硬件包括:STM32F103(任意其他款系列也可以的)、正点原子ATK-ESP8266、LED灯。实现编写STM32程序代码来传输单片机数据到原子云服务器和手机APP进行显示,同时通过手机APP和原子云服务器可以远程控制单片机,例如本节实现远程点/灭灯,以此可以扩展开发更多的功能。本专栏本系列的相关文章可查看下面链接:

嵌入式阿齐Archie 8414

【二 Deepseek+Coze案例】【 2.2 Coze + Deepseek 实现小红书爆款笔记:打造专属Agent智能体】

摘要 本文介绍了如何利用Coze平台和Deepseek模型构建自动化Agent智能体,用于生成和优化小红书爆款笔记。文章首先分析了爆款笔记的核心特征,包括精准定位、吸引标题、实用内容、精美排版和热门标签。随后提出Agent智能体的功能需求,涵盖热点追踪、内容生成与优化、数据分析及自动发布等模块。在技术实现上,详细阐述了从环境配置、数据采集到内容生成与优化的全流程,并提供了Python代码示例,展示如何调用Coze函数获取热点数据及竞品笔记。该方案通过智能化的内容创作与运营策略,帮助用户高效打造高曝光的小红书

商务合作|问题讨论|交流学习 请联系作者微信,加微信请务必注明来意,博客主页有联系方式 2271

Unity游戏开发中的C#委托与事件:从松耦合通信到事件系统实战

在软件工程中,松耦合设计是构建可维护、可扩展系统的核心原则之一,它通过减少模块间的直接依赖来提升代码的灵活性和复用性。其实现原理常依赖于观察者模式,这是一种对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会得到通知并自动更新。在C#语言中,这一模式的技术载体便是委托与事件。委托作为一种类型安全的函数指针,允许将方法作为参数传递和调用,是实现回调机制的基础;而事件则在委托之上添加了封装与安全限制,提供了标准的发布-订阅模型,有效防止了外部代码的非法赋值或触发,是实践观察者模式的关键。这项技术的

weixin_34090562的博客 289

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【Unity3D技巧】在Unity中使用事件/委托机制(event/delegate)进行GameObject之间的通信 (二) : 引入中间层NotificationCenter...

作者:王选易,出处:http://www.cnblogs.com/neverdie/ 欢迎转载,也请保留这段声明。如果你喜欢这篇文章,请点【推荐】。谢谢! 一对多的观察者模式机制有什么缺点? 想要查看完整源代码,还是访问这个项目的GitHub:https://github.com/MrNerverDie/Unity-Flappy-Bird 如果你对如何在Unity中使用事件/委托机制还不...

weixin_30379911的博客 308

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Unity3D开发之基于委托的消息框架开发之美

游戏开放中我经常遇到这样的问题,游戏中发生一个事件,我们如何把这个事件通知给其他的游戏物体,比如游戏中发生了爆炸,我们需要在一定范围内的GameObject都能感知到这一事件。 有一种方法是将对该事件感兴趣的GameObject当做成员变量保存在触发该事件的GameObject的脚本组件里,那么我们把发生事件的GameObject当作Subject(被观察者),把对该事件感兴趣的GameObje...

游戏开发、游戏引擎开发、逆向破解爱好者 295

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Unity C#事件与回调机制详解:从委托原理到实战避坑指南

在C#编程中,委托作为类型安全的函数指针,为方法调用提供了灵活的封装机制。其核心原理是通过定义方法签名模板,实现多播委托能力,支持多个方法的引用与调用。这一机制的技术价值在于实现了模块间的松耦合通信,是观察者模式的关键实现手段。在Unity开发场景中,事件作为委托的封装升级,通过发布-订阅模式广泛应用于UI交互、异步操作和系统解耦。本文聚焦Unity开发中的事件驱动编程,深入解析委托与事件的底层机制,并结合内存泄漏防范、性能优化等实战经验,帮助开发者构建更健壮的游戏架构。通过掌握事件与回调机制,开发者能有效

weixin_34274029的博客 373
上一篇: 使用unity3d需要注意到细节
下一篇: Unity AssetBundle爬坑手记
七大黍
博客等级 码龄20年 436粉丝 260原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值