Unity3D 自定义事件(事件侦听与事件触发)
先来看下效果图,图中点击 Cube(EventDispatcher),Sphere(EventListener)以及 Capsule(EventListener)会做出相应的变化,例子中的对象相互之间没有引用,也没有父子关系。

Demo 事件触发者(EventDispatcher)CubeObject.cs,挂载在 Cube 对象上
using UnityEngine;
using System.Collections; public class CubeObject : MonoBehaviour
{
void Update()
{
if (Input.GetMouseButtonDown ())
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit raycastHit = new RaycastHit();
if(Physics.Raycast(ray, out raycastHit))
{
if(raycastHit.collider.gameObject.name == "Cube")
{
// 触发事件
ObjectEventDispatcher.dispatcher.dispatchEvent(new UEvent(EventTypeName.CUBE_CLICK, "cube"), this);
}
}
}
}
}
Demo 事件侦听者(EventListener)CapsuleObject.cs,挂载在 Capsule 对象上
using UnityEngine;
using System.Collections; public class CapsuleObject : MonoBehaviour
{
private float angle;
private float targetAngle;
private float currentVelocity; void Awake()
{
// 添加事件侦听
ObjectEventDispatcher.dispatcher.addEventListener (EventTypeName.CUBE_CLICK, OnClickHandler);
} /// <summary>
/// 事件回调函数
/// </summary>
/// <param name="uEvent">U event.</param>
private void OnClickHandler(UEvent uEvent)
{
this.targetAngle = this.targetAngle == 90f ? 0f : 90f; this.StopCoroutine (this.RotationOperater ());
this.StartCoroutine (this.RotationOperater());
} IEnumerator RotationOperater()
{
while (this.angle != this.targetAngle)
{
this.angle = Mathf.SmoothDampAngle (this.angle, this.targetAngle, ref currentVelocity, 0.5f);
this.transform.rotation = Quaternion.AngleAxis(this.angle, Vector3.forward); if(Mathf.Abs(this.angle - this.targetAngle) <= ) this.angle = this.targetAngle; yield return null;
}
}
}
Demo 事件侦听者(EventListener)SphereObject.cs,挂载在 Sphere 对象上
using UnityEngine;
using System.Collections; public class SphereObject : MonoBehaviour
{
private float position;
private float targetPosition;
private float currentVelocity; void Awake()
{
// 添加事件侦听
ObjectEventDispatcher.dispatcher.addEventListener (EventTypeName.CUBE_CLICK, OnClickHandler);
} /// <summary>
/// 事件回调函数
/// </summary>
/// <param name="uEvent">U event.</param>
private void OnClickHandler(UEvent uEvent)
{
this.targetPosition = this.targetPosition == 2f ? -2f : 2f; this.StopCoroutine (this.PositionOperater ());
this.StartCoroutine (this.PositionOperater());
} IEnumerator PositionOperater()
{
while (this.position != this.targetPosition)
{
this.position = Mathf.SmoothDamp (this.position, this.targetPosition, ref currentVelocity, 0.5f);
this.transform.localPosition = new Vector3(this.transform.localPosition.x, this.position, this.transform.localPosition.z); if(Mathf.Abs(this.position - this.targetPosition) <= 0.1f) this.position = this.targetPosition; yield return null;
}
}
}
Demo 辅助类 EventTypeName.cs
using UnityEngine;
using System.Collections; public class EventTypeName
{
public const string CUBE_CLICK = "cube_click";
}
Demo 辅助类 ObjectEventDispatcher.cs
using UnityEngine;
using System.Collections; public class ObjectEventDispatcher
{
public static readonly UEventDispatcher dispatcher = new UEventDispatcher();
}
事件触发器 UEventDispatcher.cs
using System;
using System.Collections.Generic; public class UEventDispatcher
{
protected Dictionary<string, UEventListener> eventListenerDict; public UEventDispatcher()
{
this.eventListenerDict = new Dictionary<string, UEventListener>();
} /// <summary>
/// 侦听事件
/// </summary>
/// <param name="eventType">事件类别</param>
/// <param name="callback">回调函数</param>
public void addEventListener(string eventType, UEventListener.EventListenerDelegate callback)
{
if (!this.eventListenerDict.ContainsKey(eventType))
{
this.eventListenerDict.Add(eventType, new UEventListener());
}
this.eventListenerDict[eventType].OnEvent += callback;
} /// <summary>
/// 移除事件
/// </summary>
/// <param name="eventType">事件类别</param>
/// <param name="callback">回调函数</param>
public void removeEventListener(string eventType, UEventListener.EventListenerDelegate callback)
{
if (this.eventListenerDict.ContainsKey(eventType))
{
this.eventListenerDict[eventType].OnEvent -= callback;
}
} /// <summary>
/// 发送事件
/// </summary>
/// <param name="evt">Evt.</param>
/// <param name="gameObject">Game object.</param>
public void dispatchEvent(UEvent evt, object gameObject)
{
UEventListener eventListener = eventListenerDict[evt.eventType];
if (eventListener == null) return; evt.target = gameObject;
eventListener.Excute(evt);
} /// <summary>
/// 是否存在事件
/// </summary>
/// <returns><c>true</c>, if listener was hased, <c>false</c> otherwise.</returns>
/// <param name="eventType">Event type.</param>
public bool hasListener(string eventType)
{
return this.eventListenerDict.ContainsKey(eventType);
}
}
事件侦听器 UEventListener.cs
using System; public class UEventListener
{
public UEventListener() { } public delegate void EventListenerDelegate(UEvent evt);
public event EventListenerDelegate OnEvent; public void Excute(UEvent evt)
{
if (OnEvent != null)
{
this.OnEvent(evt);
}
}
}
事件参数 UEvent.cs
using System; public class UEvent
{
/// <summary>
/// 事件类别
/// </summary>
public string eventType; /// <summary>
/// 参数
/// </summary>
public object eventParams; /// <summary>
/// 事件抛出者
/// </summary>
public object target; public UEvent(string eventType, object eventParams = null)
{
this.eventType = eventType;
this.eventParams = eventParams;
}
}
Unity3D 自定义事件(事件侦听与事件触发)的更多相关文章
- nodejs事件的监听与事件的触发
nodejs事件(Events) 一.事件机制的实现 Node.js中大部分的模块,都继承自Event模块(http://nodejs.org/docs/latest/api/events.html ...
- 浏览器标签tab窗口切换时事件状态侦听
做到 是大屏项目,用的websocket,在浏览器切换标签窗口后,过了一段时间回来,页面会非常卡,所以想页面切回来的时候刷新页面,找到了这个方法,这是原来的例子.这段代码可以自己复制去做下测试 var ...
- vue02 过滤器、计算和侦听属性、vue对象的生命周期、阻止事件冒泡和刷新页面
3. Vue对象提供的属性功能 3.1 过滤器 过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中. 定义过滤器的方式有两种. 3.1.1 使用Vue.fil ...
- Spring Boot(六)自定义事件及监听
事件及监听并不是SpringBoot的新功能,Spring框架早已提供了完善的事件监听机制,在Spring框架中实现事件监听的流程如下: 自定义事件,继承org.springframework.con ...
- Laravel 事件侦听的几个方法 [Trait, Model boot(), Observer Class]
1 Trait 1.1 可以在 Trait 中定义一个静态的 bootFooBar() 方法,注:FooBar 是你的 Trait 名称 namespace App\Traits; use App\A ...
- 052_末晨曦Vue技术_处理边界情况之程序化的事件侦听器
程序化的事件侦听器 点击打开视频讲解更详细 现在,你已经知道了 $emit 的用法,它可以被 v-on 侦听,但是 Vue 实例同时在其事件接口中提供了其它的方法.我们可以: 通过 $on(event ...
- EditText 监听回车事件 避免2次触发
// 侦听回车事件 EidtText txtSN = (EditText) findViewById(R.id.txtSN); txtSN.setOnEditorActionListener(new ...
- WPF事件(一)内置路由事件
原文:WPF事件(一)内置路由事件 Windows是消息驱动的操作系统,运行其上的程序也遵照这个机制运行,随着面向对象开发平台日趋成熟,微软把消息机制封装成了更容易让人理解的事件模型,一个事件包含3个 ...
- 异形Modbus客户端 和 异形modbus服务器之间的通讯 侦听模式的modbus-tcp客户端通讯
前言 本文将使用一个Github公开的组件技术来实现一个异形ModBus TCP的客户端,方便的对异形Modbus tcp的服务器进行读写,这个服务器可以是电脑端C#设计的,也可以是特殊设备实现的,也 ...
随机推荐
- MyEclispe发布web项目-遁地龙卷风
(-1)写在前面 我用的是MyEclipse8.5. 还记得以前帮助一个女同学解决问题的时候,特意情调了要先启动服务在发布项目,其实单独的时候都是知道的,总和起来后就容易片面的给出结论.因为不会发生问 ...
- PHP学习-链接数据库
链接数据库文件:conn.php <?php $conn = mysql_connect("localhost:3306","root","us ...
- python 小试题
有个同事要帮一个朋友做一个小试题,题目如图: 由于个人在学习python路上,所以想用python 写出来这道题,来练练手,苦思冥想,再加上受同事的一些启发,加以扩展,写出代码如下: #!/usr/b ...
- 数据库模型设计PowerDesigner
Power Designer 是Sybase公司的CASE工具集,使用它可以方便地对管理信息系统进行分析设计,他几乎包括了数据库模型设计的全过程.利用Power Designer可以制作数据流程图.概 ...
- Odd Even Linked List
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note her ...
- Linux下hostname与hosts
参考:http://wp.fungo.me/linux/what-the-hell-is-hostname.html hostname 就是机器名,内核中的一个变量,可临时修改也可以永久修改 /etc ...
- 可以改变this指向的方法
this一般指向的是当前被调用者,但也可以通过其它方式来改变它的指向,下面将介绍三种方式: 1.call用作继承时: function Parent(age){ this.name=['mike',' ...
- iOS 禁止边缘滑动返回
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
- 解析 Linux 内核可装载模块的版本检查机制
转自:http://www.ibm.com/developerworks/cn/linux/l-cn-kernelmodules/ 为保持 Linux 内核的稳定与可持续发展,内核在发展过程中引进了可 ...
- IP地址的分类
IPv4 地址的分类: 一,组成 1. 使用32位地址 2. 以点分十进制表示,如172.16.0.0,每一个数字对应于8个二进制的比特串,称为一个位组(octets).如某一台主机的IP地址 ...