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

来源:互联网 发布:尿不湿推荐 知乎 编辑:程序博客网 时间:2024/05/22 11:49
这里可能需要前期准备一下c#的委托(delegate)和事件(event)方面的知识了。。。
不是很明白的,就各种谷歌吧~
需要准备二个继承与MonoBehaviour的EventDispatcher类和EventListener类。
我这里吧delegate就写在EventDispatcher里了,也可以新建一个类吧这些delegate存在里面,方便一点。。。
  1. //定义委托事件,它定义了可以代表的方法的类型                /**事件*/        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传出去。
  1. public event EventHandler MouseDown;          void OnMouseDown(){                  if (MouseDown != null)                          MouseDown (this.gameObject);         }


复制代码


以此类推,附上EventDispatcher类:
  1. 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组件。
  1. private EventDispatcher evt = null;                // Use this for initialization        void Start () {                evt = GameObject.Find("Cube1").GetComponent<EventDispatcher>();        }


复制代码
获取到目标对象后,就要将本地的响应函数,添加到EventDispatcher 的事件 委托里去。
  1. /**注册侦听器函数*/        void addEventListener(){                //给委托的事件类型变量赋值                evt.MouseDown +=OnMouseDownListener;                evt.MouseDrag += OnMouseDragLIstener;        }

复制代码
evt.MouseDown 可以简单的理解成一个delegate,+= 将本地函数(delegate规定的类型和参数)赋值进去,当然了解除监听就用 -= 啦~~

完了再写出处理函数。。。
  1. /**事件响应处理函数         * @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上去试试吧~~~


5.png
完成了。。。


有问题,大家一起研究,一起学习,一起进步~~
阅读全文
0 0
原创粉丝点击