Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411283 Posts in 69325 Topics- by 58380 Members - Latest Member: bob1029

March 29, 2024, 03:07:24 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityTownhallForum IssuesArchived subforums (read only)TutorialsUnity tutorial - Creating a simple, yet effective Event system
Pages: [1]
Print
Author Topic: Unity tutorial - Creating a simple, yet effective Event system  (Read 1502 times)
Duckbridge
Level 0
**



View Profile WWW
« on: August 21, 2015, 02:54:22 AM »

Hey again,

this is entry 2 in the Luckslinger tech series and this one will be about the ‘event system’ that we use in our games. We use this in MANY places in Luckslinger and it makes the development of the game(and other games) a lot easier and more flexible.

This system is used for dispatching in-game events and is similar to the publish-subscribe pattern

The system is quite simple, there is object A which listens to object B and then when object B wants to send a message to object A, it just dispatches, that message. An example:

Code:
    GameManager {

        Player player = new Player();
        player.AddEventListener(this.gameObject); 
       
        public void OnPlayerDied() {
            RestartGame();
        }
    }

    Player {

        Public void OnHit() {
            health--;
            if(health < 1) {
                   DispatchMessage(“OnPlayerDied”, null);
             }
        }
    }

It’s an example of an event that we actually use in Luckslinger (but ofcourse it’s not that simple in-game).

When ‘DispatchMessage’ is called, it sends a message to all the objects that are listening to the Player object, in this case it’s only the GameManager, so in the GameManger, the ‘OnPlayerDied’ function is called through the event (and no parameter is passed, you could do that if you want)

So how do you get a system like this to work? Well we’re in Luck, because in Unity this is relatively easy to do (We can also do this in Java, but I’ll do a separate post on this if people want to know how to do it).

Unity has this thing called ‘SendMessage’, which allows you to call a function on an object by it’s name (a string). And you guessed it, we will basically be using this function, but we’ll be building something around it to make it work easy!

 
The code looks like this:

Code:
    public abstract class DispatchBehaviour : MonoBehaviour {
     
     private List<GameObject> listeninggameObjects = new List<GameObject>();
     protected bool isEnabled = true;
 
     public void DispatchMessage(string message, object parameter) {
         if(listeninggameObjects != null) {
             for(int i = 0 ; i < listeninggameObjects.Count ; i++) {
                 if(listeninggameObjects[i]) {
                     listeninggameObjects[i].SendMessage(message, parameter, SendMessageOptions.DontRequireReceiver);
                 }
             }
         }   
     }
     
     public void AddEventListener(GameObject go) {
         if(go != null && !listeninggameObjects.Contains(go)) {
             listeninggameObjects.Add(go);
         }
     }
 
     public void RemoveEventListener(GameObject go) {
         listeninggameObjects.Remove (go);
     }    public virtual void Disable() {
         this.isEnabled = false;
     }
    }
 

So it is a class that is a child of MonoBehaviour (so you can extend the DispatchBehaviour class in your own classes). Which means that you could make a Player class which is able to dispatch messages to other objects by doing the following:

Code:

    public class Player : DispatchBehaviour  {
             //player code stuff
    }

Basically what the DispatchBehaviour class does is that you can add objects into the list of Listeners with the ‘AddEventListener’ function and then you can send a message to all of them in the ‘DispatchMessage(‘message’,parameter)’ function. And because you extend the DispatchBehaviour class, you can always access the functions.

The way this would work in Unity is quite simple, almost the same as what I’ve done before.
I’ll give some pseudo/example code:

Code:
    public class GameManager : MonoBehaviour {
        public void Awake() {
            Player player = this.transform.Find(“Player”).GetComponent<Player>();
            player.AddEventListener(this.gameObject);
        }

        public void OnPlayerDied() {
            Debug.Log(“Ah, you died, restart”);
        }

        public void OnPlayerDied(Player player) {
            Debug.Log(“Ah, player with “ + player.name +” died, restart”);
        }

    }

    public class Player : DispatchBehaviour {

        public void Awake() {
            Invoke(“OnFakeDied”, 2f);
        }

        public void OnFakeDied() {
            DispatchMessage(“OnPlayerDied”, null);
        }

        public void OnFakeDiedWithParameter () {
            DispatchMessage(“OnPlayerDiedWithName”, this);
        }
    }


You could probably just copy-paste this into Unity in an empty Scene with two gameObjects and just attach the correct scripts to the game Objects and it should work.

That’s it! Pretty easy right Smiley.
My name is Marciano Viereck and I’m the programmer at Duckbridge and we’ve recently released Luckslinger on Steam with a 2 man team.
Logged

Dutch indie game developer that is currently working on Luckslinger, you can follow us on Twitter and Facebook
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic