For the DungeonDiver game, we will implement a simple movement system similar to Etrian Odyssey, or D&D games: going forward will make our player move by one unit, while choosing to go to another direction will make our player rotate.
We will refine this system over the course of the project, but the implementation shown in this article is dead simple and makes for a good introduction to using Unity.
To see it in action, click on the demo link above. All the resources used are available on github.
Setting Up the Scene
In your project, simply right click in the hierarchy, go to 3D Object and add a new Cube to the scene. This cube will serve as our Player, so you can go ahead and call it Player.
Next Create a new script in the Scripts folder of your Assets (bottom of the window, if the Scripts folder does not exist, just right-click Assets, Create, Folder) and call this Script PlayerController. Once it is created, open it: it is in this file we will write the code to control our player.
GameObjects, Transforms and Lifecycle Hooks
Unity revolves around GameObjects: these are objects, such as the Cube we created before, that live in the current game scene. These GameObjects contain data, such as what is called the Transform, which contains everything about the gameobject’s position, rotation and place in the hierarchy. Our job is to specify behaviours for these game objects through scripts to create our game.
Thankfully, Unity provides developpers with a base class called MonoBehaviours: it allows our scripts to directly interface with these game objects through specific lifecycle hooks.
What are these hooks? Well for now we will only use 2 of them:
Start
This is a function called once at the start of the scene, before the first frame is rendered
Update
This function is called every frame, before rendering
Since we will be waiting for player input, we will operate within the Update hook, and capture whenever the User presses specific keys.
Putting it all Together
Considering everything I have written above, the way to implement a movement system seems straightforward:
Create a Player object in our scene
Create a PlayerController script that will capture player input in its Update method
Attach the PlayerController script to the player
Run the scene and test it out!
Coding the Movement System
As written above, Unity provides us with a lot of convenient functions to simplify our work. One of them is the Input module, which allows us to detect when a player pushes a button.
In our case, we want our player to move one unit, or rotate, ONLY once: when the player pushes an arrow key. To do this, we will use the function Input.GetKeyDown. This function returns true only on the first frame where a player has pushed a button so this is perfect for our desired effect.
As for performing the actual movement or rotation we will act directly on the player’s transform by setting the transform’s forward direction, in order to perform a rotation, or by calling the method Translate to move forward.
So here’s our code below for the PlayerController script: we use an enum to specify our directions, translate our game object by one unit on the Z axis when moving forward, and change the transform when rotating.
usingUnityEngine;publicenumDirections{ Forward, Left, Right, Backward};publicclassPlayerController : MonoBehaviour{privateTransform _TransformPlayer;// Start is called before the first frame updatevoidStart() { _TransformPlayer = gameObject.transform; }// Update is called once per framevoidUpdate() {if (Input.GetKeyDown(KeyCode.UpArrow)) {MoveForward(); } elseif (Input.GetKeyDown(KeyCode.LeftArrow)) {Rotate(Directions.Left); } elseif (Input.GetKeyDown(KeyCode.RightArrow)) {Rotate(Directions.Right); } elseif (Input.GetKeyDown(KeyCode.DownArrow)) {Rotate(Directions.Backward); } }publicvoidMoveForward() { _TransformPlayer.Translate(newVector3(0f, 0f, 1f)); }publicvoidRotate(Directionsdirection) {if (direction == Directions.Left) { _TransformPlayer.forward =- _TransformPlayer.right; } elseif (direction == Directions.Backward) { _TransformPlayer.forward =-_TransformPlayer.forward; }else { _TransformPlayer.forward = _TransformPlayer.right; } }}
Once done, we just need to attach our script to our player gameobject. Now when we run the scene, our player should react to our keyboard’s arrow keys. Neat!
In the next article, I’ll explain how to add UI elements and hook them to our movement systems, as is shown on the demo above, but also how to implement your own clickable, reactive components. This will come in handy in a variety of situations, not limited to developing mobile games.