OK, so there’s three points we need to cover :
- Detect the destruction of a PowerUp GameObject by a Bolt GameObject (I assume Bolts are bullets)
- Activate a PowerUp for a given amount of time
- Instantiate bullets
We’ll create two classes for that : Player, and PowerUpItem.
1. Detect the destruction of a PowerUp by a Bolt
Your bullets (Bolts) prefab must have a collider. Check the Physics Overview Manual page. We’re going to detect collisions on our PowerUp item, and check if it is colliding with a bolt. If that is the case, then we’ll activate the Player power up, and destroy the power up item.
To do that, let’s add a “Bolt” tag to our bolts prefab, then attach this script to your PowerUp Item GameObject.
public class ItemPowerUp : MonoBehaviour
{
Player m_Player = null;
// The SerializeField attribute allows you to edit a private field in the editor
[SerializeField]
float m_SpeedBonus = 10f;
[SerializeField]
float m_BonusDuration = 10f;
void Awake()
{
// Get a reference to your Player script
m_Player = GameObject.FindObjectOfType<Player>();
}
void OnTriggerEnter(Collider coll)
{
// If the GameObject collides with a bolt
if (coll.gameObject.tag == "Bolt")
{
if (m_Player != null)
{
m_Player.ActivateBulletSpeedPowerUp(m_SpeedBonus, m_BonusDuration);
}
// Destroy the PowerUp GameObject
Destroy(gameObject);
}
}
}
Of course, now we have to actually write Player.ActivateBulletSpeedPowerUp.
2. Activate a PowerUp
You need to use Coroutines and WaitForSeconds.
Coroutines are enumerators that can be started by a MonoBehaviour, and are executed separately by the engine, on a frame-by-frame basis. What makes them perfect for PowerUps is that they can suspend execution for a given amount of time, with WaitForSeconds.
Then you just need to change the speed of your instantiated bullets while the powerup is in effect, and revert it back to normal when the powerup is disabled. All this is done inside the Coroutine.
In Player.cs, add this :
float m_BulletSpeed = 10f;
IEnumerator BulletSpeedPowerUp(float bonusSpeed, float bonusDuration)
{
// Activate bonus
m_BulletSpeed += bonusDuration;
// After some time...
yield return new WaitForSeconds(bonusDuration);
// Deactivate it
m_BulletSpeed -= bonusDuration;
}
Then, you define a public method that will start this coroutine, and be called by the PowerUpItem.
public void ActivateBulletSpeedPowerUp(float bonusSpeed, float bonusDuration)
{
StartCoroutine(BulletSpeedPowerUp(bonusSpeed, bonusDuration));
}
Alright, so now we can get to instantiating bullets.
3. Instantiate Bolts
In Player.cs, add :
// Assign the prefab in the editor
[SerializeField]
GameObject m_BoltPrefab = null;
void InstantiateBolt()
{
GameObject bolt = Instantiate(m_BoltPrefab);
Rigidbody rb = bolt.GetComponent<Rigidbody>();
// You'll have to calculate this force depending on which direction
// you want to fire the bolt in
Vector3 force = new Vector3(1, 1, 1);
force *= m_BulletSpeed;
if (rb != null)
{
rb.AddForce(force);
}
}
And this will shoot bolts at the desired speed. So when your power up is activated, bullets will indeed go faster.
Keep in mind that I have not actually tested a single line of this code, so it might not be perfect, but it will give you a good idea on how to implement your system. Don’t forget to check the Manual and the Scripting API all the time, there’s all the information you need there. There is also nothing in my code that actually calls InstantiateBolt
, so you’ll have to figure out how to do that by yourself !
Hints :
Good luck with your game !