First, What is an Event-System? An Event-System is a collection of scripts we use to send messages between game objects without linking them through the Unity inspector. The best use of this is when you want to connect a game object of the scene to a prefab. Unity Engine doesn't allow us to do that through the inspector and the best way to get this done is by using an Event-System. What if you have 50 enemies in the game and you want to notify them all when the player dies. Without an Event-System we have to connect all the enemies to a manager or some kind of a script to do that... Think about having an array of 50 enemies. This can be solved easily using an Event-System. We will do a basic example of using this event system in the end of the article.
Well, now we know the advantages of using an Event-System. Lets start coding our own simple Event-System. First we have to get an idea on how this works.
Well, now we know the advantages of using an Event-System. Lets start coding our own simple Event-System. First we have to get an idea on how this works.
First, a script in the scene raises an event using a static method of the event manager script. Then the event manager searches for the subscribed methods for that events and invokes them all. That is the simplest explanation for this. You'll get a better understanding when you reach the end of the article.
For the Event-System we need 3 different Scripts.
- EventManager script
- EventBehaviour script
- EventEnums script
01)Event Manager
First Lets Look at how the EventManager script is written.
Event Manager script has 3 static methods with a dictionary. The dictionary key is an enum which we have named as Event here and the value is a List of actions. We use an enum as the event we raise and listen to.. You can use a string or int or whatever you want. But this is very simple as you wont get any errors by mistyping event name or such problems.
AddListener method takes two parameters. First one is the event enum and the second parameter is the method we want to invoke when the event is raised. We take the enum and check if the dictionary has a key as same as the enum Event we get. If there is a key then we add the method to the List of the enum key. If the dictionary doesn't contain the key then we create the key and a new action list and add the method to that list.
RemoveListener method works same as above but it remove the registered method from the list of the given event.
RaiseEvent method take a parameter of enum Event. It searches in the dictionary for a key as same as the enum Event we pass to the method and gets the list of actions related to that key. Then RaiseEvent method invokes all the methods in that list.
This is the basic explanation of how Event Manager works.
02)Event enum
The event enum we use is this.
There are two events as GameStart and GameOver.
03)Event Behaviour
Now we can use those 3 methods from other scripts to register and raise events. But to make this more user friendly we create another class inherited from the Unity monobehaviour. And we call it as EventBehaviour.
In the event behavior script there are two abstract methods and two virtual methods. We call the Subscribe method and OnEnable2 method when the game object is enabled using the OnEnable method provided by unity. We do the same for Unsubscribe method and OnDisable2 method to but when the gameobject is disabled using OnDisable method.
We use OnEnable2 and OnDisable2 methods to make sure that extended classes can use both OnEnable and OnDisable methods without Stopping the event registering.
Now when we create a new script which should use Event-Sytem we extend that script from this EventBehavior script as the example script shown below.
What we do is Extend the DemoScript from the EventBehaviour script. Then the IDE prompts us to Import missing abstract members. We add two methods to the EventManager using the AdListener method in the Subscribe method. And in the start method of the demo script we call the RaiseEvent method passing the GameStart Event enum to the method.. Then the event manager looks for the related methods and invokes the HandleOnGameLaunch event method. And in that method there is another event raise for the GameOver event. And then event manager invokes the HandleOnGameOverEvent method.
Using both event raise and listeners on the same script is not a practical use. So lets look at a practical use.
Example:
Now lets think there are some spheres in a scene. And we want them to change their color on a certain event.
First we add a new event to the Event enum called ColorChange.
Then we create a sphere controller script like this.
All we do here is registering the HandleOnColorChangeEvent on event manager for the ColorChange Event.
Then we add some spheres to the scene and add the SphereController script to all of them.
In addition we use a input manager script to raise the event when a specific button is pressed.
So when the E button is pressed we raise the ColorChange Event.
When we run the script and press the "E" button all the spheres would turn their color into red. It doesn't matter if have hundreds of spheres all would do the same thing if we have added the sphere controller to them.
I hope you could get a better understanding on how to use this Event-System practically. We can improve an Event-System to send various data including classes with the event, so we can pass various data between game objects. Thats up to you to think how this can be improved for your uses. In Addition I will give you a small tip. You can use another enum to specify the state of the event like if the event is start or over using an enum.
Awesome guide to make our own event manager. Keep it up!
ReplyDeleteThis is pretty nifty! How would you suggest handling a system like this where each event and corresponding action might require different arguments? Like, suppose I wanted the "ColorChange" event to have an associated Color value to change to?
ReplyDelete