因为以前用的 ActionScript 开发网页游戏,ActionScript 中的 EventDispatcher 还是非常方便以及实用的,借助 C# 强大的语言环境,做了 C# 版的 EventDispatcher 与 EventListener,但是与 ActionScript 相比,还是有一些差距,其中就没有事件冒泡机制,因为感觉用不上,或者稍加修改就可以实现同样的结果。
先来看下效果图,图中点击 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 (0))
{
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) <= 1) 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.csusing 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.Collections.Generic;
public class UEventDispatcher
{
protected IList<UEventListener> eventListenerList;
public UEventDispatcher()
{
this.eventListenerList = new List<UEventListener> ();
}
/// <summary>
/// 侦听事件
/// </summary>
/// <param name="eventType">事件类别</param>
/// <param name="callback">回调函数</param>
public void addEventListener(string eventType, UEventListener.EventListenerDelegate callback)
{
UEventListener eventListener = this.getListener(eventType);
if (eventListener == null)
{
eventListener = new UEventListener(eventType);
eventListenerList.Add(eventListener);
}
eventListener.OnEvent += callback;
}
/// <summary>
/// 移除事件
/// </summary>
/// <param name="eventType">事件类别</param>
/// <param name="callback">回调函数</param>
public void removeEventListener(string eventType, UEventListener.EventListenerDelegate callback)
{
UEventListener eventListener = this.getListener(eventType);
if (eventListener != null)
{
eventListener.OnEvent -= callback;
}
}
/// <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.getListenerList (eventType).Count > 0;
}
/// <summary>
/// 发送事件
/// </summary>
/// <param name="evt">Evt.</param>
/// <param name="gameObject">Game object.</param>
public void dispatchEvent(UEvent evt, object gameObject)
{
IList<UEventListener> resultList = this.getListenerList (evt.eventType);
foreach (UEventListener eventListener in resultList)
{
evt.target = gameObject;
eventListener.Excute(evt);
}
}
/// <summary>
/// 获取事件列表
/// </summary>
/// <returns>The listener list.</returns>
/// <param name="eventType">Event type.</param>
private IList<UEventListener> getListenerList(string eventType)
{
IList<UEventListener> resultList = new List<UEventListener> ();
foreach (UEventListener eventListener in this.eventListenerList)
{
if(eventListener.eventType == eventType) resultList.Add(eventListener);
}
return resultList;
}
/// <summary>
/// 获取事件
/// </summary>
/// <returns>The listener.</returns>
/// <param name="eventType">Event type.</param>
private UEventListener getListener(string eventType)
{
foreach (UEventListener eventListener in this.eventListenerList)
{
if(eventListener.eventType == eventType) return eventListener;
}
return null;
}
}
事件侦听器 UEventListener.cs
using System.Collections;
public class UEventListener
{
/// <summary>
/// 事件类型
/// </summary>
public string eventType;
public UEventListener(string eventType)
{
this.eventType = eventType;
}
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.Collections;
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;
}
}
下载地址:链接: http://pan.baidu.com/s/1kTJ4R9H 密码: awh6