Event system of unity open project

Time:2021-12-2

Author language

Translation from open projectWiki, the translation version is ad3e009. If you see the newer version or any omissions in the author’s article, you can leave a message or email[email protected] / [email protected]


Event system of unity open project

How to build a stable event system that allows objects to communicate with each other and avoids using singleton mode? Our solution is to use scriptableobject.

There are many reasons why we don’t use singleton mode. Singleton mode establishes a rigid connection between the two systems, so that they cannot exist alone and must rely on each other. Obviously, this will make the project difficult to maintain and reuse. If you want to test a system alone, you must test the whole game.

working principle

At the bottom of the event system, we have created a series of scriptable objects called “event channels”. They are like a radio channel, broadcasting events that other scripts (action / trigger in the figure) want to broadcast on these channels. Other scripts (event listener in the figure) can listen to a channel they care about in turn, and register their callback method (call response (s) in the figure) into the events broadcast by the channel. The figure above depicts this operation process.

Monobehaviours sends and listens for events. Scriptobject event channels are resources. Since we use them to connect the two systems, these monobehaviours can exist in two different scenes in a completely independent way.

For example, when a button is pressed, an event will be sent and broadcast on an event channels scriptobject called “button_x_pressed”. At this time, we can let one or more objects listen to the event and make different responses when the event occurs: one of them hatches many particles, one of them plays sound, and the other starts playing transition animation.

How to use

Event channel in project

Events can have parameters or no parameters. The following are some examples of event channels we use in the project.

  • Void EventsIs an event without parameters. A good application is when you need to broadcast to exit the game.
  • Int EventsIs an event that carries an int parameter during broadcast. When we unlock an achievement, we can use this event to broadcast, and the parameter is achievement ID.
  • Load EventsIt is an event to pass two parameters. One is the array of gamescene, which contains all the data of the scene we want to load, and the other is a bool value, indicating whether we want to display the interface of “loading…”.

More types of channels will be added to the project. You can find all the event channels scriptableobjects we defined in the / scripts / events / scriptableobjects / folder.

Create an event channel scriptableobject

Right click in the project window, select an event channel most suitable for your needs in “game event”, and give it an image name. Such an event channel is created and can be used at any time.

Broadcast using event channel

First hold the reference of so as the channel, and then you can send an event anywhere in the code with only one line of code. The following is an example of sending an event when an object enters the collision body of the current object.

public VoidEventChannelSO OnTriggerEnterEventChannel;

private void OnTriggerEnter(Collider other)
{
    OnTriggerEnterEventChannel.RaiseEvent();
}

Set up an event listener

There are many ways to listen for events on an event channel. The object responsible for monitoring can be a single monobehaiour, which is only used to do this, or the monitoring part can be included in a script.

In the project, an example of a mixed listener is the locationloader script. In this example, the part responsible for listening is included in the script, that is, the script is not only the container of the scenario loading method, but also a listener. This is useful when we use a listener no more than once in a project. (it is in scripts / scenemanagement / locationloader. CS) (author:?)

You can also find an example of a general listener in scripts / events / voideventslistener.cs. This script can be attached to any GameObject and listen to a voiceeventchannelso. It has a unityevent without parameters. You can associate any behavior in the game with the unityevent. When an event occurs, all behaviors associated with the unityevent will respond.

Create a new type of event channel

If you need to pass a specific number / type of parameters when calling the raise method, you can create a new type of event channel. The following is an example of inteventchannelso:

[CreateAssetMenu(menuName = "Events/Int Event Channel")]
public class IntEventChannelSO : ScriptableObject
{
    public UnityAction<int> OnEventRaised;
    public void RaiseEvent(int value)
    {
        OnEventRaised.Invoke(value);
    }
}

Replace the int variable with any parameter type you want to pass. You can also add more than one parameter.

Create a new type of listener

You can create a new listener based on the number of parameters passed when the event is triggered. The following is an example of int event listener:

[System.Serializable]
public class IntEvent : UnityEvent<int>
{
}

public class IntEventListener : MonoBehaviour
{
    public IntEventChannelSO IntGameEvent;
    public IntEvent OnEventRaised;

    private void OnEnable()
    {
        //Check if the event exists to avoid errors
        if (IntGameEvent == null)
        {
            return;
        }
        IntGameEvent.eventRaised += Respond;
    }

    private void OnDisable()
    {
        if (IntGameEvent == null)
        {
            return;
        }
        IntGameEvent.eventRaised -= Respond;
    }

    public void Respond(int value)
    {
        if (OnEventRaised == null)
        {
            return;
        }
        OnEventRaised.Invoke(value);
    }
}

More information

  • Can pass2nd Devlog VideoLet’s quickly review how we use scriptableobjects to drive event channels.
  • We first introduced the event system inEpisode 2 of the Livestream(37.55)。 Note that some details have changed since then. The in the wiki is relatively new.
  • If you want to know more about the multi parameter version of unityevent, you can seeexamples in the documentationHere, it uses four parameters.