C#内置的事件机制和Unity3D姻缘

最近因为项目,也因为一些其他事情而导致学习的停止,抽个空来记录下C#内置的事件在Unity3D中的使用。

我需要让一个物体对鼠标悬停做出事件的响应的情况下,我们通常会创建一个继承MonoBehaviour的脚本然后挂到该物体上,然后为该脚本创建OnMouseOver方法,例如我们需要悬停来改变物体颜色,可能会这样写。

using UnityEngine;
using System.Collections;

public class ChangeColor : MonoBehaviour {

    void OnMouseOver()
    {
        transform.GetComponent<Renderer>().material.color = Color.red;
    }

}

这样就实现了我们需要的目的,但是,问题又来了,我们需要让另外的对象响应该事件呢?

解决办法是保持另外对象的脚本引用,然后在你的OnMouseOver方法中调用它。这样做没问题,但是不够好。因为你需要一直保持另外一个对象的引用,如果想通知多个对象要保持多个引用。代码会变得很乱。

还有一种方法是Messages 消息 。

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

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

幸运的是有一个更好的解决办法,这就是C#内置的事件机制

我们先来看一下如何在Unity3D中使用事件机制。

public class ChangeColor : MonoBehaviour {
public delegate void EventHandler(GameObject e);
public event EventHandler MouseOver;
void OnMouseOver()
{
if (MouseOver != null)
MouseOver(this.gameObject);
}

}

我们把该脚本挂的物体A,然后新建一个脚本。

public class ChangeColor1 : MonoBehaviour {

    private GameObject _gameObject;

    // Use this for initialization
    void Start () {
        [...]
        _gameObject.GetComponent<ChangeColor>().MouseOver += Listener;
        [...]
    }

    void Listener(GameObject g)
    {

Debug.Log("响应事件的物体是 " + this.gameObject.name);
         Debug.Log("触发事件的物体是 "+g.name);

    }

}

这种方式比用消息更灵活,因为它可以被用在任何一个脚本中,而不仅仅在同一个对象附属关系中。如果在整个应用中保持一个单例模式的对象,你就可以监听任何从这个对象分发出来的事件。另外一个重要特点,同一个监听方法可以响应不同对象的事件。通过传递事件源对象的引用作为参数,你总会知道哪个对象分发了事件。

时间: 2024-10-12 13:00:09

C#内置的事件机制和Unity3D姻缘的相关文章

认识Robotlegs(三)RL内置的注入机制

Robotlegs中的注入是由注入器Injector实现,先来看看Robotlegs中哪些地方存在注入器Injector. 首先Context里面有Injector,CommandMap.MediatorMap和ViewMap里面也有Injector. Context自身内部除了有一个Injector单例之外还有CommandMap.MediatorMap.ViewMap这些单例,这些对象内部具有Injector.Robotlegs框架内部存在Injector的类基本上就是这4个,当然除了Con

WPF事件(一)内置路由事件

原文:WPF事件(一)内置路由事件 Windows是消息驱动的操作系统,运行其上的程序也遵照这个机制运行,随着面向对象开发平台日趋成熟,微软把消息机制封装成了更容易让人理解的事件模型,一个事件包含3个关键点:事件的拥有者.事件的响应者.事件的订阅关系 为了降低由事件订阅带来的耦合度和代码量,WPF推出了路由事件机制,路由事件与传统的直接事件的区别在于,直接事件激发时发送者直接将消息通过事件订阅交送给事件响应者,事件响应者使用其事件处理器方法対事件的发生做出响应.驱动程序逻辑按客户需求运行,而路由

app version updates must utilize the iOS built-in update mechanism(app的更新必须用iOS内置的更新机制)

今天有一个app审核被拒了,提示app里面包括了一个更新按钮,而app的更新必须用IOS的内置更新机制,而不是app里面含有更新视图 苹果的审核规则随时都会变,好吧,那就去掉了,重新打包上传审核

移动WEB开发之JS内置touch事件[转]

iOS上的Safari也支持click 和mouseover等传统的交互事件,只是不推荐在iOS的浏览器应用上使用click和mouseover,因为这两个事件是为了支持鼠标点击而设计 出来的.Click事件在iOS上会有半秒左右的延迟,原因是iOS要highlight接收到click的element.而 mouseover/out等事件则会被手指的点击触发.所以,在iOS上,应当抛弃传统的交互事件模型而接受一个新的事件模型.Touch事件和更高级 的Gesture事件,能让你的网页交互起来像n

使用springboot内置的缓存机制springcache

1.添加注解 加入和查询缓存:第一次查询将查询结果加入缓存,key为id,value为方法的返回结果.再次查询会从gathering中查询指定key值对应的value值.gathering负责存储所有的键值对 修改和删除操作需要删除缓存 优点:使用方便 缺点:不能设置过期时间 原文地址:https://www.cnblogs.com/gdut-lss/p/11419256.html

PHP实现事件机制实例分析

PHP实现事件机制实例分析 内置了事件机制的语言不多,php也没有提供这样的功能.事件(Event)说简单了就是一个Observer模式,实现起来很容易.但是有所不同的是,事件的监听者谁都可以加,但是只能由直接包含它的对象触发.这就有一点点难度了.php有一个debug_backtrace函数,可以得到当前的调用栈,由此可以找到判断调用事件触发函数的对象是不是直接包含它的对象的办法. <?php /** * 事件 * @edit http://www.lai18.com * @author xi

【转】使用内置MonoDevelop进行Unity3D的脚本调试

原文地址:http://blog.csdn.net/setflvet/article/details/8102586 Unity3D 3.0版本开始,支持使用MonoDevelop调试,本文所使用的是Unity3D 3.5.5f3. 一.下载并安装Unity3D(3.0以上版本)以及内置的MonoDevelop(安装Unity3D时勾上即可,如图1),记得是内置的MonoDevelop,MonoDevelop官方下载的版本是没有Unity3D调试插件的. 图1-勾选MonoDevelop 二.设

Spring内置事件以及自定义事件

1. Spring内置的事件有哪些? Spring中的事件是一个 ApplicationEvent类的子类,由实现 ApplicationEventPublisherAware 接口的类发送,实现 ApplicationListener 接口的类监听. Spring中已经定义了一组内置事件,这些事件由ApplicationContext容器发出.(ContextRefreshedEvent.ContextStartedEvent.ContextStoppedEvent.ContextClosed

在Unity3D中基于订阅者模式实现事件机制

??各位朋友,大家好,欢迎大家关注我的博客,我是秦元培,我的博客地址是http://qinyuanpei.com.今天博主想和大家分享的是在Unity3D中基于订阅者模式实现消息传递机制,我们知道Unity3D中默认提供了一种消息传递机制SendMessage,虽然SendMessage使用起来的确非常简单,可是它的这种简单是建立在付出一定的代价的基础上的.经常有朋友提及不同的模块间如何进行通信的问题,可能答案最终会落到单例模式.委托和事件机制这些关键词上,在这种情况下本文所探讨的内容可能会帮助