Today we implement active thrusters for our player ship. This is different than our speed PowerUp, so some thought as to what distinguishes them and how they interoperate is necessary. Currently, our speed PowerUp is implemented through a couple of variables and a formula for calculating our player speed. Namely:
using System.Collections;
using UnityEngine;
public class Player : MonoBehaviour
{
...
[SerializeField] private float mySpeed = 3.5f;
[SerializeField] private int speedUp = 0;
[SerializeField] private float speedUpTimer = 5f;
...
private void OnTriggerEnter2D(Collider2D other)
{
switch (other.tag)
{
...
case "SpeedPU":
if (speedUp == 0) { StartCoroutine(PowerUpSpeed()); }
break;
...
default:
break;
}
}
...
private IEnumerator PowerUpSpeed()
{
speedUp = 3;
yield return new WaitForSeconds(speedUpTimer);
speedUp = 0;
}
...
private void MovePlayer()
{
transform.Translate(new Vector3( Input.GetAxis("Horizontal")
, Input.GetAxis("Vertical")
, 0
) * Time.deltaTime * (mySpeed+speedUp));
}
...
}
All the above code does is simply adds the variables mySpeed
and speedUp
. If the PowerUp is active the value of speedUp
is set to three. If it is not, it is set to zero, thus having no affect on the speed.
So, to determine our thruster behavior we have to decide what it does to the speed formula in that final transform.Translate()
. Since our PowerUp has an additive component, perhaps we make our thrusters a multiplier. In particular, a percentage. We could equally argue our PowerUp should multiply and or thrusters add. but it doesn’t really matter (especially since multiplication is just addition anyway). The point is to be sure each is realized in a different way and they not conflict.
So for now, we’ll leave the PowerUp as is and multiply our speed by something between 1.0 and 2.0 to affect a percentage increase.
The next step is to determine how to trigger it. In this case, the requirement is to activate it with the Left Shift Key on GetKeyDown()
and deactivate it on GetKeyUp()
. Stated like that, your first inclination might be to check both something like this:
private void MovePlayer()
{
if (Input.GetKeyDown(KeyCode.LeftShift)) { myThrusters = 1.1f; }
if (Input.GetKeyUp(KeyCode.LeftShift)) { myThrusters = 1.0f; }
transform.Translate(new Vector3( Input.GetAxis("Horizontal")
, Input.GetAxis("Vertical")
, 0
) * Time.deltaTime * (mySpeed+speedUp) * myThrusters);
}
There are two things I don’t like about this though. The first is there are two checks and that seems wasteful. The second is it has a magic number (1.1f) buried in the code. The second problem can be fixed by creating another variable to track it. If we put it up at the class level, we can expose it in the Inspector as well. But that feels kinda icky also.
Solving the first problem however turns out to be really easy. Instead of taking the requirement literally, we can just understand what that means. If we activate on GetKeyDown()
and deactivate on GetKeyUp()
, what we are really saying is that while the key is down, the feature us active. GetKey()
does exactly this. If we move our thruster multiplier up to expose it in the Inspector, we can also extract out the key press logic from our main code and put it in a property instead. If the Left Shift Key is pressed, our property returns the increased thruster value, if it is not, it returns one.
using System.Collections;
using UnityEngine;
public class Player : MonoBehaviour
{
//
// Speed, Boundaries and Timers
//
[SerializeField] private float mySpeed = 3.5f;
[SerializeField] private float ThrusterIncrease = 1.1f;
...
private float Thrusters
{
get
{
if (Input.GetKey(KeyCode.LeftShift)) { return ThrusterIncrease; }
return 1;
}
}
...
private void MovePlayer()
{
transform.Translate(new Vector3( Input.GetAxis("Horizontal")
, Input.GetAxis("Vertical")
, 0
) * Time.deltaTime * (mySpeed+speedUp) * Thrusters);
}
...
}
And now we have thrusters!