Giving 3D feel in a 2D space
For our 2D space shooter, we want to give an implied feeling of depth, even if we are not using that depth. The more you can make your game or system feel like it is performing as it should in real life, the more the Player can apply to the game from their experience in the real world and it’s physics.
Up to this point in our game, the Player’s ship has been ‘sliding’ back and forth along the horizon. And while that sort of movement can be achieved in space flight, it is not what most have come to expect. We are shown fantasized space fighters that look vaguely like planes cutting through space as if they were flying through air. And there is good reason for this, Everyone has seen enough planes flying to have a firm sense of what ‘flight’ should look like. While if you look at how objects actually behave in space without atmosphere, you get some sense of ‘This is wrong’ despite knowing that what you are seeing is true. As designers, we want to avoid that ‘This is Wrong’ feeling as much as possible when building our games, unless we are specifically going for that feeling in our Players.
For this game, we are going to give the Ships an aircraft like flight profile and cause them to roll and pitch in their flight. With the top down portion of out game, we will just be working on the roll, as pitch would tilt the ship ‘up’ towards the camera or ‘down’ away from it.
In Unity, Rotation is controlled through Quaternions which use a four dimensional math. I have seen some professional mathematicians that bulk at the thought of working with Quaternions. Lucky, Unity and C# provide us a way to work with Rotations that processes the Quaternions in the background. This is Euler Angles, the ‘standard’ X,Y,Z coordinates that we are more accustom to using from position and scale.
For our purposes, we have set up a method that can handle the roll based on the input that the player is using for movement. We should be able to adapt this to our Enemies with very little changes. For the Horizontal plane and Input system the rotation directions match, luckily. So when the player moves Left, the system inputs a negative value that maxes out at -1. To roll the ship towards the Left, we have to apply a negative angle. So we can multiple the Input value by our max Roll value, here hard coded to 45. We could do this in a single line instead of a IF Else statement, but I decided to use this approach so that I can decide later to add some flare to the rolls or not. This way, we can adjust the roll start points to give a bit of ‘dead zone’ to it, or to feel that range with a bit of ‘rocking’ as the ‘pilot’ returns to level flight.
You may notice that there is a bit of layering between the roll value and the Rotation value. This is because in many cases, Unity does not like or allow a script to directly change a single value to complex values, such as Vector3s or Quaternions. So, we have Roll, which we directly alter, that is used to adjust the Quarternion SetRoll that is in turn used to update the rotation of the transform.
There is one more piece to notice in the Method. We are not changing the rotation of the Player GameObject itself, which the script is attached to. Instead we have a _shipObject that we are adjusting. If we adjusted the Player object, when we added a roll, the horizontal input would also cause the Player to ‘fall’ out of the plane of the game making it impossible for it to hit any Enemy or for them to hit it. Let’s take a look how we have the Player GameObject set up in the Hierarchy.
The Player is broken up into children objects with children of their own. The two children of the Player are Space_Fighter and Offsets. The offsets hold the position information to spawn in our weapons fire, for now just Normal and TripleShot.
The Space_Fighter_01 is the ship model (FBX) and all the associated materials. As Children to the Space_Fighter, we have anything that we want to appear attached to the ship, Shield, DamagePoints and Thrusters. So when we change the rotation of the model, each one of these will rotate with it. And since the Movement method is controlling the Player’s position, the Space_Fighter moves with it.
This all comes together to give us a smooth looking Roll as the Player strafes to the left or right while giving the feel of flight.