1 using UnityEngine;
2 using System.Collections;
3 using System.Collections.Generic;
4 //-----------------------------------------------------------
5 //Enum defining all possible game events
6 //More events should be added to the list
7 public enum EVENT_TYPE {GAME_INIT,
8 GAME_END,
9 AMMO_CHANGE,
10 HEALTH_CHANGE,
11 DEAD};
12 //-----------------------------------------------------------
13 //Singleton EventManager to send events to listeners
14 //Works with IListener implementations
15 public class EventManager : MonoBehaviour
16 {
17 #region C# properties
18 //-----------------------------------------------------------
19 //Public access to instance
20 public static EventManager Instance
21 {
22 get{return instance;}
23 set{}
24 }
25 #endregion
26
27 #region variables
28 //Internal reference to Notifications Manager instance (singleton design pattern)
29 private static EventManager instance = null;
30
31 // Declare a delegate type for events
32 public delegate void OnEvent(EVENT_TYPE Event_Type, Component Sender, object Param = null);
33
34 //Array of listener objects (all objects registered to listen for events)
35 private Dictionary<EVENT_TYPE, List<OnEvent>> Listeners = new Dictionary<EVENT_TYPE, List<OnEvent>>();
36 #endregion
37 //-----------------------------------------------------------
38 #region methods
39 //Called at start-up to initialize
40 void Awake()
41 {
42 //If no instance exists, then assign this instance
43 if(instance == null)
44 {
45 instance = this;
46 DontDestroyOnLoad(gameObject); //Prevent object from being destroyed on scene exit
47 }
48 else //Instance already exists, so destroy this one. This should be a singleton object
49 DestroyImmediate(this);
50 }
51 //-----------------------------------------------------------
52 /// <summary>
53 /// Function to add specified listener-object to array of listeners
54 /// </summary>
55 /// <param name="Event_Type">Event to Listen for</param>
56 /// <param name="Listener">Object to listen for event</param>
57 public void AddListener(EVENT_TYPE Event_Type, OnEvent Listener)
58 {
59 //List of listeners for this event
60 List<OnEvent> ListenList = null;
61
62 //New item to be added. Check for existing event type key. If one exists, add to list
63 if(Listeners.TryGetValue(Event_Type, out ListenList))
64 {
65 //List exists, so add new item
66 ListenList.Add(Listener);
67 return;
68 }
69
70 //Otherwise create new list as dictionary key
71 ListenList = new List<OnEvent>();
72 ListenList.Add(Listener);
73 Listeners.Add(Event_Type, ListenList); //Add to internal listeners list
74 }
75 //-----------------------------------------------------------
76 /// <summary>
77 /// Function to post event to listeners
78 /// </summary>
79 /// <param name="Event_Type">Event to invoke</param>
80 /// <param name="Sender">Object invoking event</param>
81 /// <param name="Param">Optional argument</param>
82 public void PostNotification(EVENT_TYPE Event_Type, Component Sender, object Param = null)
83 {
84 //Notify all listeners of an event
85
86 //List of listeners for this event only
87 List<OnEvent> ListenList = null;
88
89 //If no event entry exists, then exit because there are no listeners to notify
90 if(!Listeners.TryGetValue(Event_Type, out ListenList))
91 return;
92
93 //Entry exists. Now notify appropriate listeners
94 for(int i=0; i<ListenList.Count; i++)
95 {
96 if(!ListenList[i].Equals(null)) //If object is not null, then send message via interfaces
97 ListenList[i](Event_Type, Sender, Param);
98 }
99 }
100 //-----------------------------------------------------------
101 //Remove event type entry from dictionary, including all listeners
102 public void RemoveEvent(EVENT_TYPE Event_Type)
103 {
104 //Remove entry from dictionary
105 Listeners.Remove(Event_Type);
106 }
107 //-----------------------------------------------------------
108 //Remove all redundant entries from the Dictionary
109 public void RemoveRedundancies()
110 {
111 //Create new dictionary
112 Dictionary<EVENT_TYPE, List<OnEvent>> TmpListeners = new Dictionary<EVENT_TYPE, List<OnEvent>>();
113
114 //Cycle through all dictionary entries
115 foreach(KeyValuePair<EVENT_TYPE, List<OnEvent>> Item in Listeners)
116 {
117 //Cycle through all listener objects in list, remove null objects
118 for(int i = Item.Value.Count-1; i>=0; i--)
119 {
120 //If null, then remove item
121 if(Item.Value[i].Equals(null))
122 Item.Value.RemoveAt(i);
123 }
124
125 //If items remain in list for this notification, then add this to tmp dictionary
126 if(Item.Value.Count > 0)
127 TmpListeners.Add (Item.Key, Item.Value);
128 }
129
130 //Replace listeners object with new, optimized dictionary
131 Listeners = TmpListeners;
132 }
133 //-----------------------------------------------------------
134 //Called on scene change. Clean up dictionary
135 void OnLevelWasLoaded()
136 {
137 RemoveRedundancies();
138 }
139 //-----------------------------------------------------------
140 #endregion
141 }
1 using UnityEngine;
2 using System.Collections;
3
4 public class EnemyObject : MonoBehaviour
5 {
6 //-------------------------------------------------------
7 //C# accessors for private variables
8 public int Health
9 {
10 get{return _health;}
11 set
12 {
13 //Clamp health between 0-100
14 _health = Mathf.Clamp(value, 0, 100);
15
16 //Post notification - health has been changed
17 EventManager.Instance.PostNotification(EVENT_TYPE.HEALTH_CHANGE, this, _health);
18 }
19 }
20 //-------------------------------------------------------
21 public int Ammo
22 {
23 get{return _ammo;}
24 set
25 {
26 //Clamp ammo between 0-50
27 _ammo = Mathf.Clamp(value,0,50);
28
29 //Post notification - ammo has been changed
30 EventManager.Instance.PostNotification(EVENT_TYPE.AMMO_CHANGE, this, _health);
31 }
32 }
33 //-------------------------------------------------------
34 //Internal variables for health and ammo
35 private int _health = 100;
36 private int _ammo = 50;
37 //-------------------------------------------------------
38 //Called at start-up
39 void Start()
40 {
41 //Add myself as listener for health change events
42 EventManager.Instance.AddListener(EVENT_TYPE.HEALTH_CHANGE, OnEvent);
43 }
44 //-------------------------------------------------------
45 // Update is called once per frame
46 void Update ()
47 {
48 //If you press space bar, the health is reduce
49 if(Input.GetKeyDown(KeyCode.Space))
50 {
51 //Take some damage of space bar press
52 Health -= 5;
53 }
54 }
55 //-------------------------------------------------------
56 //Called when events happen
57 public void OnEvent(EVENT_TYPE Event_Type, Component Sender, object Param = null)
58 {
59 //Detect event type
60 switch(Event_Type)
61 {
62 case EVENT_TYPE.HEALTH_CHANGE:
63 OnHealthChange(Sender, (int)Param);
64 break;
65 }
66 }
67 //-------------------------------------------------------
68 //Function called when health changes
69 void OnHealthChange(Component Enemy, int NewHealth)
70 {
71 //If health has changed of this object
72 if(this.GetInstanceID() != Enemy.GetInstanceID()) return;
73
74 Debug.Log ("Object: " + gameObject.name + " Health is: " + NewHealth.ToString());
75 }
76 //-------------------------------------------------------
77 }