C# 事件和Unity3D

Unity3D游戏开发中的C#事件 Unity3D是现在越来越流行的3D游戏引擎,它支持JavaScript,c#和Boo语言。其中C#有一个内置的事件机制,为了响应一个GameObject的事件分发,你通常要建立一个脚本继承MonoBehaviour并且实现你需要的方法。比如你想对鼠标悬停作出反应,就要创建OnMouseOver方法。通常代码会像这个样子: void OnMouseOver () { r 阅读详情
你知道C#有一个内置的事件机制吗?这在Unity3D里也非常好用。下面举一个例子。

 

为了响应一个GameObject的事件分发,你通常要建立一个脚本继承MonoBehaviour并且实现你需要的方法。比如你想对鼠标悬停作出反应,就要创建OnMouseOver方法。通常代码会像这个样子:

 

C#代码

void OnMouseOver () {

renderer.material.color = Color.red;

}

 

 

 

这样工作没问题。但如果你想通知另外一个对象响应这个事件(OnMouseOver事件)怎么办?

 

第一种方式是保持另外对象的脚本引用,然后在你的OnMouseOver方法中调用它:

 

C#代码

public MyScript myScript;

void OnMouseOver () {

myScript.NotifyMouseOver();

}

 

 

 

这样做没问题,但是不够好。因为你需要一直保持另外一个对象的引用,如果想通知多个对象要保持多个引用。代码会变得很乱。

 

Messages 消息

 

另一个办法是用SendMessage或SendMessageUpwards方法。看上去这是解决问题的最好办法,但是这些方法存在严重的缺陷,以我的观点,你应该尽量不去使用它们。

 

这些方法的语法并不灵活,你需要传递一个方法名字的字符串,这样做很容易出错。另外这些方法只能用在同一个对象的附属关系中。换句话说你只能在下面几种情况中调用SendMessage或SendMessageUpwards方法,这些方法的脚本被关联到同一个GameObject中,或者被关联到这个GameObject的祖先关系对象中。

 

Events 事件

 

幸运的是有一个更好的解决办法,这就是C#内置的事件机制。我不在这里过多的描述机制是如何工作的,你如果有兴趣可以学习相关的知识,访问MSDN手册。(译者推荐另外一篇文章,C# 中的委托和事件)

 

现在让我们看看如何在Unity3D中使用事件机制。

 

C#代码

using UnityEngine;

public class EventDispatcher : MonoBehaviour {

public delegate void EventHandler(GameObject e);

public event EventHandler MouseOver;

void OnMouseOver () {

if (MouseOver != null)

MouseOver (this.gameObject);

}

}

 

 

如果你不知道这段代码到底干什么,先不要着急。重要的是一旦你把这段代码关联到一个GameObject,只要在整个项目的任何一个脚本中保持这个对象,你就可以像下面这样处理事件:

 

C#代码

private GameObject s;

[...]

s.GetComponent<EventDispatcher>().MouseOver += Listener;

[...]

void Listener(GameObject g) {

// g is being hovered, do something...

}

 

 

这种方式比用消息更灵活,因为它可以被用在任何一个脚本中,而不仅仅在同一个对象附属关系中。如果在整个应用中保持一个单例模式的对象,你就可以监听任何从这个对象分发出来的事件。

 

另外一个重要特点,同一个监听方法可以响应不同对象的事件。通过传递事件源对象的引用作为参数,你总会知道哪个对象分发了事件,就像我的代码展示的那样。(对于这句话可以这样理解,假如游戏中扔一颗导弹炸死了一个小兵并导致坦克减血,小兵死亡和坦克减血这两个事件都触发了同一个监听方法-玩家得分,通过传递进来的事件源对象,就能知道小兵还是坦克触发了玩家得分这个监听方法。)

 

References, controllers and MVC

 

现在让我们比较一下第一和第三种方式。在最开始的例子中(第一种方式保持另外对象的脚本引用),你需要在事件分发代码中保持监听者的对象引用,我说了这不是一个好主意。在用内置事件机制,改进的版本中(第三种方式),你需要在监听者代码中保持事件分发者的引用。你也许会问,为什么后者更好?

 

首先,分发者不需要知道自己事件的监听者是谁,不需要知道有多少监听者。它只负责事件的发送。在最开始的例子中(第一种方式),如果要告诉分发者停止通知监听者,你能想象这种程序判断有多么笨重吗?

 

事件机制中,是由监听者自己决定监听什么事件,什么时候开始监听,什么时候停止监听。像这样的对象通常用于管理程序的状态或者执行某些游戏逻辑。这个就叫做控制器,借用MVC设计模式的概念。这样我们的代码会更清晰,不易出错。(译者认为观察者设计模式更符合)

 

最后一点,我喜欢重载“+=”操作符去添加监听方法。现在你也许能够猜到,如果想结束监听某个事件,可以这么写:

 

C#代码

s.GetComponent<EventDispatcher>().MouseOver -= Listener;

 

 

当然你可以创建一个通用的EventDispatcher类,实现所有GameObject能够分发的事件。可以参看下面的代码。另外在实现OnGUI事件时要特别小心,如果想知道为什么,读读这篇文章。

 

C#代码

using UnityEngine;

using System.Collections;

public class EventDispatcher : MonoBehaviour

{

public delegate void EventHandler (GameObject e);

public delegate void CollisionHandler (GameObject e, Collision c);

public event EventHandler MouseOver;

void OnMouseOver ()

{

if (MouseOver != null)

MouseOver (this.gameObject);

}

public event EventHandler MouseDown;

void OnMouseDown ()

{

if (MouseDown != null)

MouseDown (this.gameObject);

}

public event EventHandler MouseEnter;

void OnMouseEnter ()

{

if (MouseEnter != null)

MouseEnter (this.gameObject);

}

public event EventHandler MouseExit;

void OnMouseExit ()

{

if (MouseExit != null)

MouseExit (this.gameObject);

}

public event EventHandler BecameVisible;

void OnBecameVisible ()

{

if (BecameVisible != null)

BecameVisible (this.gameObject);

}

public event EventHandler BecameInvisible;

void OnBecameInvisible ()

{

if (BecameInvisible != null)

BecameInvisible (this.gameObject);

}

public event CollisionHandler CollisionEnter;

void OnCollisionEnter (Collision c)

{

if (CollisionEnter != null)

CollisionEnter (this.gameObject, c);

}

public event CollisionHandler CollisionExit;

void OnCollisionExit (Collision c)

{

if (CollisionExit != null)

CollisionExit (this.gameObject, c);

}

}

Origin教程004:Origin图形导出 需要编辑的话,双击图形,会自动用origin软件打开图形,这种方式是最开始导出图形的功能,方式一和二都是后面增加的。如果导出的图片边距较大的时候,会影响图片的美观,可以通过。也可以设置在PPT中直接编辑,找到。解决方法是,选择一条线, 阅读详情

相关推荐

SVPWM原理与MCU/FPGA实现:从数学推导到工程实战

空间矢量调制(SVPWM)是实现高性能电机驱动控制的核心算法之一,其通过六个基本电压矢量与零矢量的伏秒平衡,在一个PWM周期内合成任意方向的旋转电压圆,相比传统SPWM可提升约15%的直流电压利用率。该技术不仅涉及扇区判断、作用时间计算、过调制限幅等数学原理,还在MCU与FPGA两种硬件平台上有不同的工程实现路径,包括中心对齐PWM配置、死区插入、定点数流水线设计等。在电动工具、无人机、机器人及车载执行器等电池供电场景中,SVPWM直接决定续航与扭矩表现。本文从数学原理出发,详细拆解MCU和FPGA实现细节

weixin_34265814的博客 300

unity踩坑填坑集——OnMouseOver没反应

情景 RPG游戏中玩家打开背包,鼠标移动到道具(类型为UI-&gt;Image)上,显示物品摘要;右键道具,则使用掉该物品。 遇到的问题 UI控件挂载包含OnMouseOver函数的脚本后,鼠标移动到该控件上但OnMouseOver未触发。 原因分析 首先我们看官方文档中对于OnMouseOver使用条件的介绍: Called every f...

VinalWang的博客 9285

LangChain4j-针对性操作Function-call+系统预设角色

如果我们想要对一些敏感信息进行针对化的操作,不仅仅是接口大模型去进行回复。比如我们现在数据库里面有一些菜品,那么用户提问,店里有多少套餐,那么云端大模型肯定是不知道的,我们希望捕获这些关键字然后进行自己的业务查询或者处理,这个时候就可以使用function-call。

DDDDDouble的博客 454

Unity委托注意+按钮委托+委托中遇到的坑

一、目的 1、想知道:Unity中的委托 二、参考 1、详解Unity中的委托与事件 https://blog.youkuaiyun.com/fuemocheng/article/details/78062166 总结:good:适合多看

qq_40544338的博客 1086

基于TMS320F28034的SCI技术简介

28034的SCI没有接入DMA总线,不过它的收发都有4级的FIFO,在一定程度上也能够缓解cpu的压力。 本文的设计思想如下: 接收:通过中断的方式,4级FIFO满后在中断里将RXDATA出栈。不过就存在这种情况,发送端发出的数据未必能填满4级FIFO,然而此时配置的是4级FIFO触发中断,所以这种情况下中断无法及时地触发。怎么办? 本文的做法是在主程序下循环读取FIFO。这样就可以确保在数据高速传输时,通过中断和主程序及时和有效地接收到总线的数据。(不过当总线波特率较低时可能中断是几...

weixin_48388779的博客 1406

实测避坑:华为Atlas 300I DUO推理卡部署Qwen1.5,性能对比3090与完整配置流程

本文深度评测华为Atlas 300I DUO推理卡在部署Qwen1.5-14B大模型时的性能表现,并与RTX 3090进行对比。通过实测数据展示硬件参数、部署流程及性能优化建议,揭示国产AI加速卡在LLM推理中的独特优势与适用场景,为开发者提供完整的配置指南和避坑方案。

weixin_29083475的博客 790

UnityEvent与C#事件系统性能对比

在Unity中实现事件系统有两种方式:一种是使用C#内建的event关键字,另一种是UnityEvent类。有开发者对二者的性能分别进行了详细的分析,本文将为大家分享两种方式的对比及各自的适用场景。 首先要说明的是,UnityEvent的初衷是方便开发者直接在检视面板中编辑事件及事件回调函数,简化开发流程。使用C#内置的event需要手动编写代码且无法直接编辑。建议开发者按照需求来选择合适的方式。

su9257的博客 5666

Agentic AI上下文工程架构终极指南:全面解决智能体理解问题

在开始架构设计前,我们需要先明确两个核心概念——Agentic AI和上下文工程。Agentic AI(智能体AI)是具备自主目标、环境交互、任务分解能力的AI系统。自主性:不需要人类逐步指令,能自己规划任务(比如“帮我订机票”→自动分解为“查航班→选座位→填信息→支付”);动态性:能根据环境变化调整行为(比如订机票时发现航班延误,自动改签到下一班);连续性:能记住历史交互(比如“上次你说喜欢靠窗位,这次帮你预留了”)。

AI开发架构师 1116

unity中鼠标与物体的交互

unity实践中,鼠标与2d、3d物体吉交互的方法总结记录

rempter的博客 802

三态门Multisim电路仿真——硬件工程师笔记

三态门原理及应用摘要 三态门是具有高电平(1)、低电平(0)和高阻态(Z)三种输出的逻辑电路,通过使能端(EN)控制状态切换。高阻态时输出端等效断路,避免信号冲突。其核心应用包括: 总线系统:多设备共享总线时,仅使能选中设备的三态门,其余保持高阻态,防止干扰。 数据选择器:利用三态门切换多路输入信号,简化电路设计。 实现方式分两种: TTL三态门(三极管构成):低电平使能有效,仿真验证输出逻辑与高阻态。 MOS三态门(MOS管构成):高电平使能有效,仿真显示使能信号控制输出状态。 文中还附硬件工程师笔试面试

XU157303764的博客 2004

RK3588高速接口实战-PCIE

摘要: RK3588的PCIe接口支持PCIe 3.0x4和PCIe 2.1x1/x2,具备Root Complex和Endpoint模式,适用于NVMe SSD、5G模块等高速设备。硬件设计需注意85Ω/100Ω阻抗匹配、220nF AC耦合电容及100MHz参考时钟。设备树需配置控制器节点、PHY模式和IOMMU映射(RC模式用iommu-map,EP模式用iommus)。调试时可通过lspci检查链路状态,dmesg查看训练日志,perf分析性能。常见问题包括设备识别失败(检查复位时序、PHY配置)、

weiyvyy的博客 499

C#事件和Unity3d

Unity与C# Delegate组合的事件系统

2880

【WRF湿度调整策略】WRF/ERA5湿度数据对比

【WRF湿度调整策略】WRF/ERA5湿度数据对比

WW、forever的博客 117

C# 事件和 Unity3D

Unity3D是現在越來越流行的3D遊戲引擎,它支援JavaScript,c#和Boo語言。如果你是個Unity3D的愛好者,但只會JavaScript。這裏有一篇文章關於處理事件和消息傳遞,也許更適合你。A Useful Messaging System你知道C#有一個內置的事件機制嗎?這個東東在Unity3D裏也非常好用。下面舉一個例子。為了回應一個GameObject的事件分發,...

dieyi4726的博客 179

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Unity3D C# 委托和事件(之二)

你知道C#有一个内置的事件机制吗?这个东东在Unity3D里也非常好用。下面举一个例子。  为了响应一个GameObject的事件分发,你通常要建立一个脚本继承MonoBehaviour并且实现你需要的方法。比如你想对鼠标悬停作出反应,就要创建OnMouseOver方法。通常代码会像这个样子:  C#代码   void OnMouseOver () {     rend

Unity 1万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C#事件和Unity3D

你知道C#有一个内置的事件机制吗?这个东东在Unity3D里也非常好用。下面举一个例子。  为了响应一个GameObject的事件分发,你通常要建立一个脚本继承MonoBehaviour并且实现你需要的方法。比如你想对鼠标悬停作出反应,就要创建OnMouseOver方法。通常代码会像这个样子:  void OnMouseOver () { renderer.material.color

無 763

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

【转】C#事件和Unity3D

你知道C#有一个内置的事件机制吗?这个东东在Unity3D里也非常好用。下面举一个例子。 为了响应一个GameObject的事件分发,你通常要建立一个脚本继承MonoBehaviour并且实现你需要的方法。比如你想对鼠标悬停作出反应,就要创建OnMouseOver方法。通常代码会像这个样子: C#代码  void OnMouseOver () {    renderer.material.colo

無 604
上一篇: unity3d 数学基础与数学辅助类
下一篇: unity3d与web交互的方法
Linux先生
博客等级 码龄20年 97粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值