Revisiting the Unity 2D Space Shooter | Part 2: Prototyping the Player
Objective: Create a prototype player object and set up the behavior for it to move around on screen.
To begin prototyping the player, it’s important to take a step back and think through how we want the player to maneuver around the level. Some things to consider:
- Is the player’s movement strictly bound by the screen?
- Should the player be able to teleport from one side to the other if it moves too far in either direction, like Mario Bros.?
- How fast should the player move, and would that movement speed potentially need to be altered in game?
First, the Player Object
In the previously created project in Part 1, the default ‘SampleScene’ can be deleted and replaced with a new scene containing only a Main Camera and Directional Light by selecting File > New Scene and then saving it as ‘Game’. The prototyping will be done using primitives so right-click in the Hierarchy, choose 3D Object > Cube, and rename the cube object to ‘Player’.
A material can be added to the player to distinguish it by creating a Materials folder in the Project tab and then right-clicking the folder, selecting Create > Material, and renaming the material to ‘Player_mat’. It can then be set to any preferred color and simply drag and dropped onto the player in the Scene.
Side Note: it’s important to keep an organized folder structure, especially as new assets and packages are added, so create a base folder to house each of your subsequent folder such as Materials, Scenes, and Scripts.
Next, the Background
By default, the Main Camera uses a Skybox under ‘Clear Flags’ to pull in light data primarily for use with 3D games. Clear Flags determines what’s displayed in the empty areas of the camera’s view, and this can be changed to ‘Solid Color’ to display a single color for the background. The desired background color can be selected immediately below the Clear Flags variable.
Since it’s unknown what any potential end users might be using for a display to play this game, the aspect ratio can also be changed to a 16:9 Aspect (HD standard) in the Game view so that the game’s proportions stay consistent across devices and screens.
The Game view should now resemble the below depending on what colors were selected for the Player_mat and background:
Then, the Movement
Following in line with traditional arcade space shooter gameplay, the player will be ‘flying’ up towards enemies in the scene which means it’ll most likely need its movement restricted vertically on the y-axis so that it doesn’t go too far above or below the screen. The same could be done horizontally along the x-axis, but in this case the player will be allowed to move/teleport from one side to the other if it moves too far left or right.
The bounds of the screen can be found by selecting the player and using the transform tool to move it up, down, left, and right. The player’s X and Y transform values can then be used to set how far on each axis the player should be allowed to move before either stopping or being teleported.
Create a new ‘Scripts’ folder and add a C# Script the same way the previous material was created and name it ‘PlayerBounds’. The X and Y transform values can then be stored as a variable and used to restrict the player’s movement via an ApplyBounds() method:
This script uses the current position of the player and first checks if that position along the x-axis is greater than or less than the min and max bounds value. If either is true, the player’s position on the x-axis is set to the opposite bounds, either min or max, teleporting it from one side to the other.
Next, the player’s current y position is clamped by the min and max values set for the y-axis so that its unable to go above or below those values.
Finally, the players transform.position is set back to the current position factoring in those bounds. The ApplyBounds() method can now be called in Update() to have it applied each frame.
With the bounds in place, the actual movement of the player can be calculated in a separate PlayerMovement script via the method below:
This method is also called in Update() and uses the player’s horizontal and vertical inputs (WASD or left, right, up, and down) to get an input direction. That input direction can then be multiplied by a speed variable and Time.deltaTime within Unity’s transform.Translate() method to smoothly move around the scene.
Separating the bounds and movement functionality into their own scripts follows the Single Responsibility Principle of classes having one responsibility and purpose to decouple behaviors and allow for easier changes to be made. To apply the scripts, drag and drop them onto the player cube/game object similar to its material.
The player should now be able to maneuver effortlessly around its designated area in the scene: