This tutorial will show how to use the messaging system I describe in this article
in order to handle input from the player.
I have packaged the files from the messaging system into a zip archive that can be downloaded here:
We will create a very basic game in Unity where a box moves about on screen according to the user pressing the arrow keys.
A playable version of the game can be found here:
The complete unity project source can be downloaded here:
We use the Game Events System to facilitate communication between Game Objects. This allows game objects to operate independently of other objects in the system – making them simpler.
For this tutorial we will make the following game objects:
- Input Manager: This object polls Unity for input events and dispatches relevant game events.
- Player Move Event: This object is sent through the game event system by the Input Manager when it detects that the player has pressed an arrow key.
- Cube: This is the cube that the player moves around. It will have a script attached that listens for Player Move Events and moves the cube accordingly.
Setting Up The Project:
Create a new project and set the project preferences for 2D.
Create a project set up for 2D.
import events system
Unzip the Game Events System (download link at the top of the page) and place the folder in your ‘Assets’ directory. You may want to create a folder within ‘Assets’ called ‘scripts’ to hold game scripts. This helps keep the project organised.
Save the project and the scene. Name it whatever you want (even Jeremiah) as there will only be one scene in this project.
Create Manager Object
The ‘Manager’ object is an empty Unity object that we can place in a scene and attach Manager scripts to. Manager scripts might be responsible for things like processing input from the keyboard, keeping score or playing sounds. In this tutorial the only manager script we will use is an Input Manager.
create empty empty object
To create the manager object, first create an empty game object from the GameObject menu in Unity.
Set its name to manager because it will hold all the
Create a CSharp script in your scripts directory and attach it to the Manager object.
Create a Cube
Now create the cube that the player will move around with the arrow keys.
From the hierarchy create a cube. There is no need to change any of the settings in the inspector.
You can change the name if you like. I named it ‘cube’ because I am imaginative like that sometimes.
Create Player Move Event
We will now create the Player Move Event. This event is used for communication between the Input Manager and the Cube.
Create a CSharp script and name it ‘PlayerMovetEvent’. Don’t attach this script to any objects.
The source for the Player Move Event can be viewed here:
First we declare that we are using the GameEvents namespace. This will give us access to the classes in the Game Events System.
We then declare the PlayerMoveEvent class. We inherit GameEvent so that this object can be treated as a Game Event by the Game Events System.
public class PlayerMoveEvent : GameEvent
Next we declare what data the event will hold. It will hold a Vector3 object describing the direction the player wishes to move. We make this field public so that other classes can access it easily.
public Vector3 direction;
Finally we declare the constructor. We want it to accept a Vector3 as its class data. This data will come from the Input Manager when it wishes to dispatch this event.
public PlayerMoveEvent(Vector3 d)
In the constructor’s body we store the data that was passed to the constructor.
direction = d;
Create Player Movement Script
The player movement script will be attached to the Cube object. It will listen for Player Move Events and move the Cube accordingly.
The source for this script can be viewed here:
First we declare that we are using the GameEvents namespace. This allows us to access the classes defined in the Game Events System:
We then declare the PlayerMovement class. It inherits properties from GameEventListener that allow the Game Events System to treat it as an event listener:
public class PlayerMovement : MonoBehaviour, GameEventListener
We define a constant that dictates how much the cube should move by on each frame:
const float moveAmount = 0.1f;
Next we define what the object should do when it starts. We use Unity’s built in Start() function to do this.
We want this object to register itself as a Game Event Listener so that the Game Event Manager will dispatch events to it.
Next we define what to do when an event is received.
In order for our object to behave as a Game Event Listener we must define a public method called Event Received. The Game Event Manager will call this method when it dispatches an event.
The method accepts one argument, which is a Game Event.
public void eventReceived(GameEvent e)
The Game Event System notifies all listeners of all events. So the Player Movement object must test to see if this event is relevant to it.
This is done by checking the type of the Game Event to see if it is a Player Move Event.
if (e is PlayerMoveEvent)
Next we read the data from the event. We are looking for a Vector3 object called direction.
Because we have already verified that the Game Event received was a Player Move Event we can treat it as such.
Vector3 d = (e as PlayerMoveEvent).direction;
Finally, we move the Cube in the direction specified by the event by the amount specified in our moveAmount constant.
attach player movement
Now we can attach the Player Movement script to the Cube. This will allow the script to move the cube when it receives a Player Move Event.
Making the Input Manager
The Input Manager is responsible for checking the Unity system to see if a key has been pressed and then dispatching relevant Player Move Events.
The code for the input manager can be viewed here:
First we declare that we are using the Game Events namespace. This allows us to access the classes defined in the Game Events System.
Next we define the input manager. It does not need to inherit any properties from the Game Events System so we define it as a MonoBehaviour class, which allows it to interface with the Unity Engine.
public class InputManager : MonoBehaviour
Next we define the class data. We will store the Key Code for each of the arrow keys so that we can reference them easily when checking for key presses. Here is an example of how we store these Key Codes:
private KeyCode up = KeyCode.UpArrow;
Finally we must check the Unity engine for the status of the keys. We do this in a FixedUpdate because we will be moving the cube and this will help ensure smooth movement if the framerate of the game spikes.
void FixedUpdate ()
We check the status of the relevant key using the Unity Input object.
Input.GetKey(KeyCode) will return true if the key has been pressed so now we dispatch a Player Move Event with the correct direction.
We have created a system for moving an object on screen via key press. Using the Game Events System to accomplish this may seem cumbersome at first and you may think it would be better to put all the logic in a script attached to the cube.
The benefit of this method is that all of the system components are completely isolated. The Player Movement script does not worry about where the input is coming from. It is only concerned with moving the player when a move event is received.
It would be easy now to write a more advanced input manager that allows, for example, keys to be re-mapped by the user. Implementing this new input system would not require the Player Movement script to be altered.
As a system grows in complexity these benefits will become clear. Having all objects decoupled greatly aids in maintaining, organizing and updating the code.
Try to think of some ideas on how you could extend this system. Could you write a Sound Manager that would play footstep sounds when the player moves?