Welcome back to day 87 and part 3 of adding the Magnet Power Up. In the last post, we finally created the magnet effect that allowed the coin to hover towards you.
However, there’s one problem: how do we know if the magnet power is gone? We don’t, there’s no indication at all! In today’s post, we’re going to:
- Add an audio cue that will play when our power-up is available once we finish this, we will move on to add 2 more power-ups and we will move on to implement something else in our game!
Step 1: Adding an Audio Cue
Step 1.1: Finding the Audio
The first thing we need to do is find a magnet sound that we might want to use. For this, I went back to freesounds.org.
I had to dig around, but I eventually found something that I thought would work well as a magnet sound effect.
It’s called Square Buzz.
The sound effect is 12 seconds long, which won’t be long enough for our background sound. So instead, what we’re going to do is that we’re going to make this run on a loop.
However, if you look at the audio in the image, we can see that the audio gets quieter near the end.
To fix this, we need to cut it. I don’t have any sound editing software so I decided to see if I can find an online solution.
Luckily for us, such a solution exists! I went to a site called mp3cut.net.
To use it, you simply must upload your audio file and then you can choose the part of the song to cut off.
Because we’re looping the music, we must make sure that the audio can transition from the end to the beginning.
To accomplish this, I chose to start playing the sound when it is quieter and end it when it’s becoming quieter.
Specifically, my start time is: 0:00.4 and my end time is 0:10.9.
For this tutorial, it doesn’t matter too much. If you don’t want to go through the process, you can find the audio in the CubeFlyer Github repo in the Music folder. The mp3 file is called Magnet.
- Drag the MP3 file into our project hierarchy (if it’s not called Magnet, rename it Magnet)
Now we have the music file, it’s time to add it to our game.
Step 1.2: Play the Power Up Music
Now that we have the power-up music, it’s time to use it, we need to play the sound effect.
Normally, I thought a good place to put it would have been the Magnet, but a problem with that is that if our magnet disappears, so does our sound, so we can’t do that (plus as we move away from it, the sound goes away too).
So instead I decided on a power-up, let’s add it to the player.
Specifically, in the PlaneCollider
.
Here’s the script:
using UnityEngine;
public class PlaneCollider : MonoBehaviour
{
public GameObject PlaneObject;
public GameObject Explosion;
public AudioClip MagnetSFX;
private SoundManager _soundManager;
void Start()
{
_soundManager = GetComponent<SoundManager>();
}
void OnTriggerEnter(Collider other)
{
print(other + " name " + other.name);
switch (other.tag) {
case "Coin":
CoinCollision(other);
break;
case "Magnet":
MagnetCollision(other);
break;
default:
CheckUnTaggedCollision(other);
break;
}
}
private void CoinCollision(Collider other) {
Coin coin = other.GetComponent<Coin>();
coin.Collect();
GameManager.Instance.CollectCoin();
}
private void MagnetCollision(Collider other)
{
PlayerManager.Instance.AddPowerUp(PlayerManager.PowerUpType.Magnet);
Magnet magnet = other.GetComponent<Magnet>();
_soundManager.PlayBackgroundClip(MagnetSFX);
magnet.Collect();
}
private void CheckUnTaggedCollision(Collider other) {
if (other.name.Contains("Cube")) {
EnemyCollision();
}
}
private void EnemyCollision()
{
Instantiate(Explosion, PlaneObject.transform.position, Quaternion.identity);
Destroy(PlaneObject);
PlayerManager.Instance.GameOver();
GameUIManager.Instance.GameOver(gameObject);
CameraManager.Instance.GameOver();
}
}
Looking at the Fields
Like what we’ve probably already seen before, we’re adding our Audio to our script.
public AudioClip MagnetSFX
– The music clip for our Magnet effect private SoundManager _soundManager
– The class we wrote to help us play our sound effects (we need to add it to our game object later)
Walking Through the Code
We already have the system to detect game objects we collided against, we just need to write some code to detect our magnet and then play the sound effect.
- In
Start()
, we create an instance of our _soundManager
by grabbing it from our Game
Object. - In
MagnetCollision()
, we use our _soundManager
and play a backgroundClip
with our Magnet sound. If you recall, the background clip will keep playing the power-up sound effect until we tell it to stop. We’ll do this later.
Setting Up the Script
We need to do a couple of things to get the script to work:
- Add
Magnet
to the Magnet SFX
slot in our PlaneCollider
. - Add the
SoundManager
script to our Player
component.
Step 1.3: Stop the Power-Up Music
Now that we have our power-up background music playing, the next thing that we need to do is to know when to stop our background music.
Our background music is directly tied to how long our power-up is playing, specifically, if our power-up goes away, so does our sound effect!
What manages our power-ups? The PlayerManager
script! We’re just going to make a small change:
using UnityEngine;
using System.Collections.Generic;
public class PlayerManager : MonoBehaviour
{
public static PlayerManager Instance;
public enum PlayerState { Alive, Dead }
public GameObject Player;
public GameObject MagnetCollider;
public enum PowerUpType { Magnet }
private Dictionary<PowerUpType, PowerUp> powerUpDictionary;
private float powerUpDuration = 30f;
private List<PowerUpType> itemsToRemove;
public PlayerState CurrentState
{
get { return _currentState; }
private set { _currentState = value; }
}
private PlayerState _currentState;
void Start ()
{
if (Instance != null)
{
Destroy(gameObject);
return;
}
Init();
}
void Update()
{
foreach (KeyValuePair<PowerUpType, PowerUp> entry in powerUpDictionary)
{
entry.Value.Duration -= Time.deltaTime;
if (entry.Value.Duration <= 0)
{
itemsToRemove.Add(entry.Key);
}
}
foreach (PowerUpType powerUpType in itemsToRemove)
{
switch (powerUpType)
{
case PowerUpType.Magnet:
Transform magnetCollider = Player.transform.Find("Magnet Collider(Clone)");
print(magnetCollider);
Destroy(magnetCollider.gameObject);
magnetCollider = null;
break;
}
powerUpDictionary.Remove(powerUpType);
}
itemsToRemove.Clear();
if (powerUpDictionary.Count == 0)
{
Player.GetComponent<SoundManager>().StopBackgroundClip();
}
}
private void Init()
{
Instance = this;
CurrentState = PlayerState.Alive;
powerUpDictionary = new Dictionary<PowerUpType, PowerUp>();
itemsToRemove = new List<PowerUpType>();
}
public void GameOver()
{
CurrentState = PlayerState.Dead;
}
public void AddPowerUp(PowerUpType powerUpType)
{
switch (powerUpType)
{
case PowerUpType.Magnet:
if (powerUpDictionary.ContainsKey(powerUpType))
{
break;
}
Instantiate(MagnetCollider, Player.transform.position,
Quaternion.identity, Player.transform);
break;
}
powerUpDictionary[powerUpType] = new PowerUp(powerUpDuration);
}
public bool ContainsPowerUp(PowerUpType powerUpType)
{
return powerUpDictionary.ContainsKey(powerUpType);
}
}
Walking through the Code
- All we’re doing extra here is adding an extra
if
statement at the end of Update()
, we just check to see if we have any power-ups in our list and if we don’t, we’ll stop our background music.
One caveat here is that because this is in Update()
, we’ll actually be stopping our background every frame. Luckily, if we take a peek at StopBackgroundClip()
, we’ll see that we first check to see if any audio clip is even playing, thus averting the problem.
End Day 87
That’s it! Now when we pick up the magnet effect, our magnet sound will play on repeat until the power-up expires.
Having sound is great, but we’re not going to end just there. In the next article, we’re going to look at adding a visual particle effect that shows that we have a magnet effect.
Stay tuned for the next article!