关于Unity的委托事件处理脚本之间的交互

来源:互联网 发布:高清网络摄像机多少钱 编辑:程序博客网 时间:2024/06/05 03:35
这里可能需要前期准备一下c#的委托(delegate)和事件(event)方面的知识了。。。
不是很明白的,就各种谷歌吧~
需要准备二个继承与MonoBehaviour的EventDispatcher类和EventListener类。
我这里吧delegate就写在EventDispatcher里了,也可以新建一个类吧这些delegate存在里面,方便一点。。。
  1. //定义委托事件,它定义了可以代表的方法的类型
  2.        
  3.         /**事件*/
  4.         public delegate void EventHandler(GameObject e); 
  5.         /**碰撞检测*/
  6.         public delegate void CollisionHandler(GameObject e,Collision c);
  7.         /**触发器检测*/
  8. public delegate void TriggerHandler(GameObject e,Collider other);
  9.         /**控制器碰撞检测*/
  10.         public delegate void ControllerColliderHitHandler(GameObject e,ControllerColliderHit hit);
  11.         /**新关卡被加载进来*/
  12.         public delegate void LevelWasLoadedHandler(GameObject e,int level);
复制代码
委托定义好了,其实这些就类似于方法参数一样。。。可意会不好言传啊。。。

然后重写MonoBehaviour支持的那些时间响应函数:
比如OnMouseDown();
首先定义一个EventHandler 这个委托的事件。。。然后再OnMouseDown响应函数里对他进行操作。。
如果某个GameObject侦听了这个事件并写出了响应函数(响应函数即是定义事件的委托delegate),那么在重写的OnMouseDown函数类就会调用执行这个传进来的delegate并且把this.gameObject传出去。
  1. public event EventHandler MouseDown; 
  2.         void OnMouseDown(){ 
  3.                 if (MouseDown != null) 
  4.                         MouseDown (this.gameObject);
  5.         }
复制代码


以此类推,附上EventDispatcher类:
  1. using System;
  2. using UnityEngine; 
  3. /** 
  4. *  基于MonoBehaviour的一个事件派发类
  5. * A simple event dispatcher - allows to listen to events in one GameObject from another GameObject
  6. *
  7. *
  8. *  Usage:
  9. *  Add this script to the object that is supposed to dispatch events. 
  10. *  In another objects follow this pattern to register as listener at intercept events:
  11.  
  12.     void Start () {
  13.         EventDispatcher ev = GameObject.Find("someObject").GetComponent<EventDispatcher>();
  14.         ev.MouseDown += ListeningFunction; // Register the listener (and experience the beauty of overloaded operators!)
  15.     }

  16.     void ListeningFunction (GameObject e) {
  17.         e.transform.Rotate(20, 0, 0); // 'e' is the game object that dispatched the event
  18.         e.GetComponent<EventDispatcher>().MouseDown -= ListeningFunction; // Remove the listener
  19.     }
  20.     
  21. *  This class does not implement all standards events, nor does it allow dispatching custom events, 
  22. *  but you shold have no problem adding all the other methods.
  23. *
  24. * date: 2013.8.21
  25. */ 
  26. public class EventDispatcher:MonoBehaviour{
  27.        
  28.         //定义委托事件,它定义了可以代表的方法的类型
  29.        
  30.         /**事件*/
  31.         public delegate void EventHandler(GameObject e); 
  32.         /**碰撞检测*/
  33.         public delegate void CollisionHandler(GameObject e,Collision c);
  34.         /**触发器检测*/
  35.         public delegate void TriggerHandler(GameObject e,Collider other);
  36.         /**控制器碰撞检测*/
  37.         public delegate void ControllerColliderHitHandler(GameObject e,ControllerColliderHit hit);
  38.         /**新关卡被加载进来*/
  39.         public delegate void LevelWasLoadedHandler(GameObject e,int level);
  40.                 
  41.        
  42.        
  43.        
  44.         public event EventHandler MouseEnter; 
  45.         void OnMouseEnter(){ 
  46.                 if (MouseEnter != null)  //如果有方法注册委托变量
  47.                         MouseEnter(this.gameObject); //通过委托调用方法
  48.         }
  49.        
  50.         public event EventHandler MouseOver;
  51.         void OnMouseOver(){ 
  52.                 if (MouseOver != null) 
  53.                         MouseOver (this.gameObject);
  54.         }
  55.        
  56.         public event EventHandler MouseExit; 
  57.         void OnMouseExit(){ 
  58.                 if (MouseExit != null) 
  59.                         MouseExit (this.gameObject);
  60.         }
  61.        
  62.         public event EventHandler MouseDown; 
  63.         void OnMouseDown(){ 
  64.                 if (MouseDown != null) 
  65.                         MouseDown (this.gameObject);
  66.         }
  67.        
  68.         public event EventHandler MouseUp; 
  69.         void OnMouseUp(){ 
  70.                 if (MouseUp != null) 
  71.                         MouseUp (this.gameObject);
  72.         }
  73.        
  74.         public event EventHandler MouseDrag; 
  75.         void OnMouseDrag(){ 
  76.                 if (MouseDrag != null) 
  77.                         MouseDrag (this.gameObject);
  78.         }
  79.        
  80.         /**当renderer(渲染器)在任何相机上可见时调用OnBecameVisible*/
  81.         public event EventHandler BecameVisible; 
  82.         void OnBecameVisible (){ 
  83.                 if (BecameVisible != null) 
  84.                         BecameVisible (this.gameObject); 
  85.         } 
  86.         /**当renderer(渲染器)在任何相机上都不可见时调用OnBecameInvisible*/
  87.         public event EventHandler BecameInvisible; 
  88.         void OnBecameInvisible (){ 
  89.                 if (BecameInvisible != null) 
  90.                         BecameInvisible (this.gameObject); 
  91.         } 
  92.         public event EventHandler Enable;
  93.         void OnEnable(){
  94.                 if(Enable != null)
  95.                         Enable(this.gameObject);
  96.         }
  97.         public event EventHandler Disable;
  98.         void OnDisable(){
  99.                 if(Disable != null)       
  100.                         Disable(this.gameObject);
  101.         }
  102.          public event EventHandler Destroy;
  103.         void OnDestroy(){
  104.                 if(Destroy != null)
  105.                         Destroy(this.gameObject);
  106.         }
  107.         /**在相机渲染场景之前调用*/
  108.         public event EventHandler PreRender;
  109.         void OnPreRender(){
  110.                 if(PreRender != null)
  111.                         PreRender(this.gameObject);
  112.         }
  113.         /**在相机完成场景渲染之后调用*/
  114.         public event EventHandler PostRender;
  115.         void OnPostRender(){
  116.                 if(PostRender != null)
  117.                         PostRender(this.gameObject);
  118.         }
  119.         /**在相机场景渲染完成后被调用*/
  120.         public event EventHandler RenderObject;
  121.         void OnRenderObject(){
  122.                 if(RenderObject != null)
  123.                         RenderObject(this.gameObject);
  124.         }
  125.        

  126.        
  127.         public event EventHandler ApplicationPause;
  128.         void OnApplicationPause(){
  129.                 if(ApplicationPause != null)
  130.                         ApplicationPause(this.gameObject);
  131.         }
  132.         /**当玩家获得或失去焦点时发送给所有游戏物体*/
  133.         public event EventHandler ApplicationFocus;
  134.         void OnApplicationFocus(){
  135.                 if(ApplicationFocus != null)
  136.                         ApplicationFocus(this.gameObject);
  137.         }
  138.         public event EventHandler ApplicationQuit;
  139.         void OnApplicationQuit(){
  140.                 if(ApplicationQuit != null)
  141.                         ApplicationQuit(this.gameObject);
  142.         }
  143.        
  144.        
  145.        
  146.         public event TriggerHandler TriggerEnter;
  147.         void OnTriggerEnter(Collider other){
  148.                 if(TriggerEnter != null)
  149.                         TriggerEnter(this.gameObject,other);
  150.         }
  151.         public event TriggerHandler TriggerExit;
  152.         void OnTriggerExit(Collider other){
  153.                 if(TriggerExit != null)
  154.                         TriggerExit(this.gameObject,other);
  155.         }
  156.         public event TriggerHandler TriggerStay;
  157.         void OnTriggerStay(Collider other){
  158.                 if(TriggerStay != null)
  159.                         TriggerStay(this.gameObject,other);
  160.         }
  161.        
  162.         public event ControllerColliderHitHandler controllerColliderHit;
  163.           void OnControllerColliderHit(ControllerColliderHit hit){
  164.                 if(controllerColliderHit != null)
  165.                         controllerColliderHit(this.gameObject,hit);
  166.         }
  167.        
  168.     public event CollisionHandler CollisionEnter; 
  169.     void OnCollisionEnter (Collision c){ 
  170.         if (CollisionEnter != null) 
  171.             CollisionEnter (this.gameObject, c); 
  172.     } 
  173.          public event CollisionHandler CollisionStay; 
  174.     void OnCollisionStay (Collision c){ 
  175.         if (CollisionStay != null) 
  176.             CollisionStay (this.gameObject, c); 
  177.     } 
  178.        
  179.     public event CollisionHandler CollisionExit; 
  180.     void OnCollisionExit (Collision c){ 
  181.         if (CollisionExit != null) 
  182.             CollisionExit (this.gameObject, c); 
  183.     }
  184.        
  185.         public event LevelWasLoadedHandler LevelWasLoaded;
  186.         void OnLevelWasLoaded(int level){
  187.                 if(LevelWasLoaded != null)
  188.                         LevelWasLoaded(this.gameObject,level);
  189.         }
复制代码
写好了派发事件的类拖到需要派发事件出来的组件上,然后再来注册和侦听吧,下面写出EventListener类做出侦听的步骤。。
首先需要获取目标组件上的EventDispatcher组件。
  1. private EventDispatcher evt = null;
  2.        
  3.         // Use this for initialization
  4.         void Start () {
  5.                 evt = GameObject.Find("Cube1").GetComponent<EventDispatcher>();
  6.         }
复制代码
获取到目标对象后,就要将本地的响应函数,添加到EventDispatcher 的事件 委托里去。
  1. /**注册侦听器函数*/
  2.         void addEventListener(){
  3.                 //给委托的事件类型变量赋值
  4.                 evt.MouseDown +=OnMouseDownListener;
  5.                 evt.MouseDrag += OnMouseDragLIstener;
  6.         }
复制代码
evt.MouseDown 可以简单的理解成一个delegate,+= 将本地函数(delegate规定的类型和参数)赋值进去,当然了解除监听就用 -= 啦~~

完了再写出处理函数。。。
  1. /**事件响应处理函数
  2.          * @param GameObject e 事件源的GameObject对象
  3.          * <li> 事件响应函数的参数,参见EventDispatcher类中的相应事件Handler的参数个数
  4.          * */
  5.         void OnMouseDownListener(GameObject e){
  6.                 print("on mouse down..");
  7.                 e.transform.Rotate(20, 0, 0);
  8.                 //移除侦听函数
  9.                 e.GetComponent<EventDispatcher>().MouseDown -= OnMouseDownListener;
  10.         }
  11.        
  12.         void OnMouseDragLIstener(GameObject e){
  13.                 print("on mouse drag..");
  14.         }
复制代码


附上EventListener源码:
  1. using UnityEngine;
  2. using System.Collections;
  3. /**
  4. * 响应事件
  5. * */
  6. public class EventListener : MonoBehaviour {
  7.        
  8.         private EventDispatcher evt = null;
  9.        
  10.         // Use this for initialization
  11.         void Start () {
  12.                 evt = GameObject.Find("Cube1").GetComponent<EventDispatcher>();
  13.                 addEventListener();
  14.         }
  15.         /**注册侦听器函数*/
  16.         void addEventListener(){
  17.                 //给委托的事件类型变量赋值
  18.                 evt.MouseDown +=OnMouseDownListener;
  19.                 evt.MouseDrag += OnMouseDragLIstener;
  20.         }
  21.        
  22.         // Update is called once per frame
  23.         void Update () {
  24.        
  25.         }
  26.         /**事件响应处理函数
  27.          * @param GameObject e 事件源的GameObject对象
  28.          * <li> 事件响应函数的参数,参见EventDispatcher类中的相应事件Handler的参数个数
  29.          * */
  30.         void OnMouseDownListener(GameObject e){
  31.                 print("on mouse down..");
  32.                 e.transform.Rotate(20, 0, 0);
  33.                 //移除侦听函数
  34.                 //e.GetComponent<EventDispatcher>().MouseDown -= OnMouseDownListener;
  35.         }
  36.        
  37.         void OnMouseDragLIstener(GameObject e){
  38.                 print("on mouse drag..");
  39.         }
  40.        
  41. }
复制代码
。。代码码玩了,绑定到响应的Cube上去试试吧~~~


5.png
2013-9-17 15:37:03 上传
下载附件(73.59 KB)

完成了。。。


有问题,大家一起研究,一起学习,一起进步~~

0 0