Speed PowerDown

Objective: Create a Speed PowerDown so when a player picks one up, it decreases the player’s speed.

Natalia DaLomba
Women in Technology
4 min readAug 17, 2023

--

So we’ve created several PowerUps before, but now it’s time to create our first PowerDown. A PowerUp improves a certain attribute of the player while a PowerDown will worsen an attribute of the player.

The Speed PowerDown will have the following features:

  • The player’s speed will be set to 3 for a duration of 5 seconds.
  • Holding shift to perform Speed Boost will not be available while Speed PowerDown is active.
  • The player’s thruster sprite right behind the ship will look dimmed.
  • An audio clip will play when picking up a PowerDown.
  • If the player collects a Speed PowerUp and then within the next 5 seconds a Speed PowerDown, the PowerDown will override the Speed PowerUp until the PowerDown’s time is done. Then there will be no Speed PowerUp or Speed PowerDown active after the 5 seconds are up (unless you happened to pick up a different kind of PowerUp).
  • The Speed PowerDown icon displays in the HUD while it’s active.

For reference, this is our Collectable parent class we will be inheriting from:

We start by creating a child class that inherits from Collectable called PowerDown:

Then, we write the SpeedPowerDown script that inherits from PowerDown:

So far, our logic says if the Speed PowerDown collides with the player, we play an audio clip and then we run the (soon to be created) SpeedPowerDownActive method. Then Speed PowerDown is destroyed.

So let’s go to the script that manages player movement and speed. Ours is called ShipMovementController2D. The existing, unrelated code is hidden to better understand what we’re looking at. Initially we write the below:

public class ShipMovementController2D : MonoBehaviour {
[SerializeField] private float speedPowerDownSpeed = 3;
//this image will be used in the HUD
[SerializeField] private Image speedPowerDownImage;

private new AudioSource audio;

//we add the below IsSpeedPowerDownActive property to this list to
//accurately determine if Speed Boost is available or not
private bool isSpeedPowerDownActive;
public bool IsSpeedPowerDownActive => isSpeedPowerDownActive;

//speed boost is only available when several bools are false, including
//when the speed powerdown is't active
public bool IsSpeedBoostAvailable => !IsSpeedPowerUpActive &&
!IsSpeedPowerDownActive && IsSpeedBoostActive &&
!IsSpeedBoostCoolingDown;

private void Start() {
transform.position = Vector3.zero;
audio = GetComponent<AudioSource>();
}

private void StartSpeedBoost() {
if ((Input.GetKeyDown(KeyCode.LeftShift) || Input.GetKeyDown(KeyCode.
RightShift)) && IsSpeedBoostAvailable)
StartCoroutine(SpeedBoostCoroutine());
else if ((Input.GetKeyDown(KeyCode.LeftShift) || Input.
GetKeyDown(KeyCode.RightShift)) && !IsSpeedBoostAvailable) {
//when speed boost isn't available and the player , scale the speed boost bar
//by playing an animation. set the audio clip to the no speed
//boost clip and play it
speedBoostBar.NoSpeedBoostBarUIScaling();
audio.clip = noSpeedBoostClip;
audio.Play();
}
}
}

Make sure to drag and drop all of the required fields we set up here in the Unity Editor. Moving forward, let’s add the following at the bottom of the ShipMovementController2D script:

public void SpeedPowerDownActive() {
isSpeedPowerDownActive = true;
speedPowerDownImage.enabled = true;
speedPowerUpImage.enabled = false;
speed = speedPowerDownSpeed;
thrusterSprite.color = Color.grey;
//we need to create a coroutine to keep track of the 5 seconds
//speed powerdown is active. then we will start it here
StartCoroutine();
}

The last piece to our code is to write the SpeedPowerDownShutDown() coroutine and call it:

public void SpeedPowerDownActive() {
isSpeedPowerDownActive = true;
speedPowerDownImage.enabled = true;
speedPowerUpImage.enabled = false;
speed = speedPowerDownSpeed;
thrusterSprite.color = Color.grey;
//called and started the coroutine
StartCoroutine(SpeedPowerDownShutDown());
}

private IEnumerator SpeedPowerDownShutDown() {
WaitForSeconds wait = new WaitForSeconds(5);
while (IsSpeedPowerDownActive) {
yield return wait;
speedPowerDownImage.enabled = false;
speed = 5;
thrusterSprite.color = Color.white;
isSpeedPowerDownActive = false;
}
}

Our last bit of business is to display the Speed PowerDown icon in our HUD while it’s active. We already wrote the functionality above so all we need to do is set up our canvas.

We also have the image component unchecked to begin with so the icon will not be displayed initially — only when Speed PowerDown is active (according to our code).

This is the animation for our Speed PowerDown that will be translating down the screen.

Now everything works!

--

--

Natalia DaLomba
Women in Technology

A Unity C# developer inspired by game design logic used to create digital adventures. https://www.starforce.games/devlog/