• Unity3D C#事件管理:EventManager


    原文地址:http://bbs.9ria.com/thread-153258-1-1.html

    原project地址:https://github.com/djandrew/UnityEventManager

    多年的Flash开发。我很赞赏Flash的事件系统。

    Uinty对象通信所使用的方法SendMessage在多数情况下是工作正常,但假设在一个具有无数引用其它对象的GameObject的大型项目进行反射,那问题就来了。


    我用C#在Uinty中所写的第一个东西,就是管理抽象类的事件管理系统。

    究其核心。EventManager使用也是SendMessage。并对游戏对象[gameObject]有直接引用,但若有事件发生。其便会对需求进行分解,不同的类间会有信息共享,这样事件对象就知道怎样互相通信。



    若有不论什么建议或修正。欢迎留言。



    EventManager.cs(十按。本链接为凝视译版,若认为某译不妥请对比英文版自行勘误)

    1. /*
    2.     Event Manager
    3.     Static manager for handling an event driven communication model in Unity.
    4.     This is similar to Adobe Flash's event listener model used in ActionScript.
    5.      
    6.     Copyright © 2012 Dustin Andrew
    7.     dustin.andrew@gmail.com
    8.     http://www.dustinandrew.me/
    9.      
    10.     This program is free software: you can redistribute it and/or modify
    11.     it under the terms of the GNU General Public License as published by
    12.     the Free Software Foundation, either version 3 of the License, or 
    13.     any later version.

    14.     This program is distributed in the hope that it will be useful,
    15.     but WITHOUT ANY WARRANTY; without even the implied warranty of
    16.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    17.     GNU General Public License for more details.

    18.     http://www.gnu.org/licenses/
    19. */

    20. /* 
    21. *  Setup:
    22. *  Create an empty GameObject and add the EventManager script to it.
    23. *  Create custom event classes that extend the CustomEvent.

    24. *  Restrictions & Tips:
    25. *  DO NOT add event listeners in the Awake() method! 
    26. *  This is used by the EventManager to initialize.
    27. *  Change this class' Execution Order to before default time if you need to work around this.
    28. *  Use the Start() method to setup your events.
    29. *  Make event listener callback functions public.
    30. *  Extend the CustomEvent class when creating your events.
    31. *  Use custom variables in your custom events over the arguments hashtable to maintain class abstraction
    32. *  Clean up and remove event listeners when objects are destroyed.
    33. *  Events are not received if the listener gameObject.active is false.

    34. *  Examples:

    35. *  // setup event listeners
    36. *  void Start() {
    37. *      EventManager.instance.addEventListener(CustomEventObj.EVENT_TO_LISTEN_TO, gameObject, "OnSomethingHappened");
    38. *  }
    39. *  
    40. *  // remove event listeners
    41. *  void OnDestroy() {
    42. *      if (gameObject) {
    43. *          // remove a single event
    44. *          EventManager.instance.removeEventListener(CustomEventObj.EVENT_TO_LISTEN_TO, gameObject);
    45. *          // remove all events
    46. *          EventManager.instance.removeAllEventListeners(gameObject);
    47. *      }
    48. *  }

    49. *  // get values passed by events
    50. *  public void OnSomethingHappened(CustomEventObj evt) {
    51. *      Debug.Log((datatype)evt.arguments["value"]);
    52. *      // or if using custom vars instead of arguments hashtable
    53. *      Debug.Log(evt.rockOn);      
    54. *  }

    55. *  // dispatch events
    56. *  void TriggerEvent() {
    57. *      CustomEventObj evt = new CustomEventObj(CustomEventObj.EVENT_TO_TRIGGER);
    58. *      evt.arguments.Add("value", 3);
    59. *      EventManager.instance.dispatchEvent(evt);
    60. *  }

    61. *  // create custom events
    62. *  using UnityEngine;
    63. *  using System.Collections;

    64. *  public class CustomEventObj : CustomEvent {

    65. *      // event types
    66. *      public static string MY_EVENT_1 = "my_event_1";
    67. *      public static string MY_EVENT_2 = "my_event_2";

    68. *      // optionally add custom variables instead of using the arguments hashtable
    69. *      public int myCustomEventVar1 = 0;
    70. *      public bool rockOn = true;

    71. *      public CustomEventObj(string eventType = "") {
    72. *         type = eventType;
    73. *      }
    74. *  }

    75. */

    76. using UnityEngine;
    77. using System.Collections;

    78. // internal event listener model
    79. internal class EventListener {
    80.     public string name;
    81.     public GameObject listener;
    82.     public string function; 
    83. }

    84. // Custom event class, extend when creating custom events
    85. public class CustomEvent {
    86.      
    87.     private string _type;
    88.     private Hashtable _arguments = new Hashtable();
    89.      
    90.     // constructor
    91.     public CustomEvent(string eventType = "") {
    92.         _type = eventType;
    93.     }
    94.      
    95.     // the type of event
    96.     public string type {
    97.         get { return _type; }
    98.         set { _type = value; }
    99.     }
    100.      
    101.     // the arguments to pass with the event
    102.     public Hashtable arguments {
    103.         get { return _arguments; }
    104.         set { _arguments = value; }
    105.     }
    106. }

    107. public class EventManager : MonoBehaviour {
    108.      
    109.     // singleton instance
    110.     public static EventManager instance;
    111.      
    112.     // settings
    113.     public bool allowSingleton = true; // EventManager class will transfer between scene changes.
    114.     public bool allowWarningOutputs = true;
    115.     public bool allowDebugOutputs = true;
    116.      
    117.     private static bool _created = false;   
    118.     private Hashtable _listeners = new Hashtable(); 
    119.      
    120.     // setup singleton if allowed
    121.     public void Awake() {
    122.         if (!_created && allowSingleton) {
    123.             DontDestroyOnLoad(this);
    124.             instance = this;
    125.             _created = true;
    126.             Setup();
    127.         } else {
    128.             if (allowSingleton) {
    129.                 if (EventManager.instance.allowWarningOutputs) {
    130.                     Debug.LogWarning("Only a single instance of " + this.name + " should exists!");
    131.                 }
    132.                 Destroy(gameObject);
    133.             } else {
    134.                 instance = this;
    135.                 Setup();
    136.             }
    137.         }
    138.     }
    139.      
    140.     // clear events on quit
    141.     public void OnApplicationQuit() {
    142.         _listeners.Clear();
    143.     }
    144.      
    145.     // PUBLIC *******************************
    146.      
    147.     // Add event listener
    148.     public bool addEventListener(string eventType, GameObject listener, string function) {
    149.         if (listener == null || eventType == null) {
    150.             if (allowWarningOutputs) {
    151.                 Debug.LogWarning("Event Manager: AddListener failed due to no listener or event name specified.");
    152.             }
    153.             return false;
    154.         }
    155.         recordEvent(eventType);
    156.         return recordListener(eventType, listener, function);
    157.     }
    158.      
    159.     // Remove event listener
    160.     public bool removeEventListener(string eventType, GameObject listener) {
    161.         if (!checkForEvent(eventType)) return false;
    162.          
    163.         ArrayList listenerList = _listeners[eventType] as ArrayList;
    164.         foreach (EventListener callback in listenerList) {
    165.             if (callback.name == listener.GetInstanceID().ToString()) {
    166.                 listenerList.Remove(callback);
    167.                 return true;
    168.             }
    169.         }
    170.         return false;
    171.     }
    172.      
    173.     // Remove all event listeners
    174.     public void removeAllEventListeners(GameObject listener) {
    175.         foreach (EventListener callback in _listeners) {
    176.             if (callback.listener.GetInstanceID().ToString() == listener.GetInstanceID().ToString()) {
    177.                 _listeners.Remove(callback);
    178.             }
    179.         }
    180.     }
    181.      
    182.     // Dispatch an event
    183.     public bool dispatchEvent(CustomEvent evt) {
    184.         string eventType = evt.type;
    185.         if (!checkForEvent(eventType)) {
    186.             if (allowWarningOutputs) {
    187.                 Debug.LogWarning("Event Manager: Event "" + eventType + "" triggered has no listeners!");
    188.             }
    189.             return false;
    190.         }
    191.          
    192.         ArrayList listenerList = _listeners[eventType] as ArrayList;
    193.         if (allowDebugOutputs) {
    194.             Debug.Log("Event Manager: Event " + eventType + " dispatched to " + listenerList.Count + ((listenerList.Count == 1) ? " listener." : " listeners."));
    195.         }
    196.         foreach (EventListener callback in listenerList) {
    197.             if (callback.listener && callback.listener.active) {
    198.                 callback.listener.SendMessage(callback.function, evt, SendMessageOptions.DontRequireReceiver);
    199.             }
    200.         }
    201.         return false;
    202.     }
    203.      
    204.     // PRIVATE *******************************
    205.      
    206.     private void Setup() {
    207.         // TO DO: Self create GameObject if not already created
    208.     }
    209.      
    210.     // see if event already exists
    211.     private bool checkForEvent(string eventType) {
    212.         if (_listeners.ContainsKey(eventType)) return true;
    213.         return false;
    214.     }
    215.      
    216.     // record event, if it doesn't already exists
    217.     private bool recordEvent(string eventType) {
    218.         if (!checkForEvent(eventType)) {
    219.             _listeners.Add(eventType, new ArrayList());
    220.         }
    221.         return true;
    222.     }
    223.      
    224.     // delete event, if not already removed
    225.     private bool deleteEvent(string eventType) {
    226.         if (!checkForEvent(eventType)) return false;
    227.         _listeners.Remove(eventType);
    228.         return true;
    229.     }
    230.      
    231.     // check if listener exists
    232.     private bool checkForListener(string eventType, GameObject listener) {
    233.         if (!checkForEvent(eventType)) {
    234.             recordEvent(eventType);
    235.         }
    236.          
    237.         ArrayList listenerList = _listeners[eventType] as ArrayList;
    238.         foreach (EventListener callback in listenerList) {
    239.             if (callback.name == listener.GetInstanceID().ToString()) return true;
    240.         }
    241.         return false;
    242.     }
    243.      
    244.     // record listener, if not already recorded
    245.     private bool recordListener(string eventType, GameObject listener, string function) {
    246.         if (!checkForListener(eventType, listener)) {
    247.             ArrayList listenerList = _listeners[eventType] as ArrayList;
    248.             EventListener callback = new EventListener();
    249.             callback.name = listener.GetInstanceID().ToString();
    250.             callback.listener = listener;
    251.             callback.function = function;
    252.             listenerList.Add(callback);
    253.             return true;
    254.         } else {
    255.             if (allowWarningOutputs) {
    256.                 Debug.LogWarning("Event Manager: Listener: " + listener.name + " is already in list for event: " + eventType);
    257.             }
    258.             return false;
    259.         }
    260.     }
    261. }
    复制代码



    原文链接:http://www.dustinandrew.me/blog/2012/10/9/unity3d-c-event-manager.html

    翻译词数:225

  • 相关阅读:
    3个检测浏览器UserAgent信息的网站
    linux系统下配置网桥(CentOS 5.5)
    squid封禁不带UserAgent的请求
    iptables透明网桥无法使用透明代理错误
    Squid修改用户浏览器的Useragent信息
    MySQL主从复制(MasterSlave)与读写分离(MySQLProxy)实践
    js中格式化时间
    js获取当前月的第一天和最后一天
    JS String.toDate
    Js获取当前日期时间及其它操作
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7287220.html
Copyright © 2020-2023  润新知