使用委托和事件在类之间传值

xiaoxiao2021-02-28  23

这里可能需要前期准备一下c#的委托(delegate)和事件(event)方面的知识了。。。 不是很明白的,就各种谷歌吧~ 需要准备二个继承与MonoBehaviour的EventDispatcher类和EventListener类。 我这里吧delegate就写在EventDispatcher里了,也可以新建一个类吧这些delegate存在里面,方便一点。。。 //定义委托事件,它定义了可以代表的方法的类型 /**事件*/ public delegate void EventHandler(GameObject e); /**碰撞检测*/ public delegate void CollisionHandler(GameObject e,Collision c); /**触发器检测*/ public delegate void TriggerHandler(GameObject e,Collider other); /**控制器碰撞检测*/ public delegate void ControllerColliderHitHandler(GameObject e,ControllerColliderHit hit); /**新关卡被加载进来*/ public delegate void LevelWasLoadedHandler(GameObject e,int level); 委托定义好了,其实这些就类似于方法参数一样。。。可意会不好言传啊。。。 然后重写MonoBehaviour支持的那些时间响应函数: 比如OnMouseDown(); 首先定义一个 EventHandler 这个委托的事件。。。然后再OnMouseDown响应函数里对他进行操作。。 如果某个 GameObject 侦听了这个事件并写出了响应函数(响应函数即是定义 事件的 委托delegate ),那么在重写的 OnMouseDown函数类就会调用执行这个传进来的delegate并且把this.gameObject传出去。 public event EventHandler MouseDown; void OnMouseDown(){ if (MouseDown != null) MouseDown (this.gameObject); } 复制代码 以此类推,附上EventDispatcher类: using System; using UnityEngine; /** * 基于MonoBehaviour的一个事件派发类 * A simple event dispatcher - allows to listen to events in one GameObject from another GameObject * * * Usage: * Add this script to the object that is supposed to dispatch events. * In another objects follow this pattern to register as listener at intercept events: void Start () { EventDispatcher ev = GameObject.Find("someObject").GetComponent<EventDispatcher>(); ev.MouseDown += ListeningFunction; // Register the listener (and experience the beauty of overloaded operators!) } void ListeningFunction (GameObject e) { e.transform.Rotate(20, 0, 0); // 'e' is the game object that dispatched the event e.GetComponent<EventDispatcher>().MouseDown -= ListeningFunction; // Remove the listener } * This class does not implement all standards events, nor does it allow dispatching custom events, * but you shold have no problem adding all the other methods. * * date: 2013.8.21 */ public class EventDispatcher:MonoBehaviour{ //定义委托事件,它定义了可以代表的方法的类型 /**事件*/ public delegate void EventHandler(GameObject e); /**碰撞检测*/ public delegate void CollisionHandler(GameObject e,Collision c); /**触发器检测*/ public delegate void TriggerHandler(GameObject e,Collider other); /**控制器碰撞检测*/ public delegate void ControllerColliderHitHandler(GameObject e,ControllerColliderHit hit); /**新关卡被加载进来*/ public delegate void LevelWasLoadedHandler(GameObject e,int level); public event EventHandler MouseEnter; void OnMouseEnter(){ if (MouseEnter != null) //如果有方法注册委托变量 MouseEnter(this.gameObject); //通过委托调用方法 } public event EventHandler MouseOver; void OnMouseOver(){ if (MouseOver != null) MouseOver (this.gameObject); } public event EventHandler MouseExit; void OnMouseExit(){ if (MouseExit != null) MouseExit (this.gameObject); } public event EventHandler MouseDown; void OnMouseDown(){ if (MouseDown != null) MouseDown (this.gameObject); } public event EventHandler MouseUp; void OnMouseUp(){ if (MouseUp != null) MouseUp (this.gameObject); } public event EventHandler MouseDrag; void OnMouseDrag(){ if (MouseDrag != null) MouseDrag (this.gameObject); } /**当renderer(渲染器)在任何相机上可见时调用OnBecameVisible*/ public event EventHandler BecameVisible; void OnBecameVisible (){ if (BecameVisible != null) BecameVisible (this.gameObject); } /**当renderer(渲染器)在任何相机上都不可见时调用OnBecameInvisible*/ public event EventHandler BecameInvisible; void OnBecameInvisible (){ if (BecameInvisible != null) BecameInvisible (this.gameObject); } public event EventHandler Enable; void OnEnable(){ if(Enable != null) Enable(this.gameObject); } public event EventHandler Disable; void OnDisable(){ if(Disable != null) Disable(this.gameObject); } public event EventHandler Destroy; void OnDestroy(){ if(Destroy != null) Destroy(this.gameObject); } /**在相机渲染场景之前调用*/ public event EventHandler PreRender; void OnPreRender(){ if(PreRender != null) PreRender(this.gameObject); } /**在相机完成场景渲染之后调用*/ public event EventHandler PostRender; void OnPostRender(){ if(PostRender != null) PostRender(this.gameObject); } /**在相机场景渲染完成后被调用*/ public event EventHandler RenderObject; void OnRenderObject(){ if(RenderObject != null) RenderObject(this.gameObject); } public event EventHandler ApplicationPause; void OnApplicationPause(){ if(ApplicationPause != null) ApplicationPause(this.gameObject); } /**当玩家获得或失去焦点时发送给所有游戏物体*/ public event EventHandler ApplicationFocus; void OnApplicationFocus(){ if(ApplicationFocus != null) ApplicationFocus(this.gameObject); } public event EventHandler ApplicationQuit; void OnApplicationQuit(){ if(ApplicationQuit != null) ApplicationQuit(this.gameObject); } public event TriggerHandler TriggerEnter; void OnTriggerEnter(Collider other){ if(TriggerEnter != null) TriggerEnter(this.gameObject,other); } public event TriggerHandler TriggerExit; void OnTriggerExit(Collider other){ if(TriggerExit != null) TriggerExit(this.gameObject,other); } public event TriggerHandler TriggerStay; void OnTriggerStay(Collider other){ if(TriggerStay != null) TriggerStay(this.gameObject,other); } public event ControllerColliderHitHandler controllerColliderHit; void OnControllerColliderHit(ControllerColliderHit hit){ if(controllerColliderHit != null) controllerColliderHit(this.gameObject,hit); } public event CollisionHandler CollisionEnter; void OnCollisionEnter (Collision c){ if (CollisionEnter != null) CollisionEnter (this.gameObject, c); } public event CollisionHandler CollisionStay; void OnCollisionStay (Collision c){ if (CollisionStay != null) CollisionStay (this.gameObject, c); } public event CollisionHandler CollisionExit; void OnCollisionExit (Collision c){ if (CollisionExit != null) CollisionExit (this.gameObject, c); } public event LevelWasLoadedHandler LevelWasLoaded; void OnLevelWasLoaded(int level){ if(LevelWasLoaded != null) LevelWasLoaded(this.gameObject,level); } } 写好了派发事件的类拖到需要派发事件出来的组件上,然后再来注册和侦听吧,下面写出EventListener类做出侦听的步骤。。 首先需要获取目标组件上的EventDispatcher组件。 private EventDispatcher evt = null; // Use this for initialization void Start () { evt = GameObject.Find("Cube1").GetComponent<EventDispatcher>(); } 复制代码 获取到目标对象后,就要将本地的响应函数,添加到 EventDispatcher 的事件 委托里去。 /**注册侦听器函数*/ void addEventListener(){ //给委托的事件类型变量赋值 evt.MouseDown +=OnMouseDownListener; evt.MouseDrag += OnMouseDragLIstener; } 复制代码 evt.MouseDown 可以简单的理解成一个delegate,+= 将本地函数(delegate规定的类型和参数)赋值进去,当然了解除监听就用 -= 啦~~ 完了再写出处理函数。。。 /**事件响应处理函数 * @param GameObject e 事件源的GameObject对象 * <li> 事件响应函数的参数,参见EventDispatcher类中的相应事件Handler的参数个数 * */ void OnMouseDownListener(GameObject e){ print("on mouse down.."); e.transform.Rotate(20, 0, 0); //移除侦听函数 e.GetComponent<EventDispatcher>().MouseDown -= OnMouseDownListener; } void OnMouseDragLIstener(GameObject e){ print("on mouse drag.."); } 复制代码 附上EventListener源码: using UnityEngine; using System.Collections; /** * 响应事件 * */ public class EventListener : MonoBehaviour { private EventDispatcher evt = null; // Use this for initialization void Start () { evt = GameObject.Find("Cube1").GetComponent<EventDispatcher>(); addEventListener(); } /**注册侦听器函数*/ void addEventListener(){ //给委托的事件类型变量赋值 evt.MouseDown +=OnMouseDownListener; evt.MouseDrag += OnMouseDragLIstener; } // Update is called once per frame void Update () { } /**事件响应处理函数 * @param GameObject e 事件源的GameObject对象 * <li> 事件响应函数的参数,参见EventDispatcher类中的相应事件Handler的参数个数 * */ void OnMouseDownListener(GameObject e){ print("on mouse down.."); e.transform.Rotate(20, 0, 0); //移除侦听函数 //e.GetComponent<EventDispatcher>().MouseDown -= OnMouseDownListener; } void OnMouseDragLIstener(GameObject e){ print("on mouse drag.."); } } 。。代码码玩了,绑定到响应的Cube上去试试吧~~~ 完成了。。。 有问题,大家一起研究,一起学习,一起进步~~
转载请注明原文地址: https://www.6miu.com/read-1000246.html

最新回复(0)