【原创】Unity3D 自定义事件(事件侦听与事件触发)

因为以前用的 ActionScript 开发网页游戏,ActionScript 中的 EventDispatcher 还是非常方便以及实用的,借助 C# 强大的语言环境,做了 C# 版的 EventDispatcher 与 EventListener,但是与 ActionScript 相比,还是有一些差距,其中就没有事件冒泡机制,因为感觉用不上,或者稍加修改就可以实现同样的结果。

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

115608_sL7X_2423137.jpg

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

转载于:https://my.oschina.net/wangjiajun/blog/483647

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值