Problem with using IEnumerator for method, c#

So in order to use ‘yield return new WaitForSeconds();’ I needed to return IEnumerator for my PlayerFire(); method in order to not get compiler errors. However, now that I can play the game, the method doesn’t seem to do anything though it is still being called. I’m not clear on why this is and any explanation or a better way to do this without using WaitForSeconds function would be helpful.

using UnityEngine;
using System.Collections;

public class ShipControls : MonoBehaviour 
{
	public bool pausedState;
	public float speed;
	public float nextFire;
	public float fireRate;
	public float fireRate2;
	public int playerLives;
	public int powerup;
	public int shootForce;
	private Vector3 moveDirection;
	public Rigidbody shipProjectile;
	public Rigidbody shipProjectile1;
	public Rigidbody shipProjectile2;
	public Rigidbody shipProjectile3;
	public GameObject playerShip;
	
	void Awake()
	{
		pausedState = false;
		speed = 3.0F;
		nextFire = 0.0F;
		fireRate = 0.25F; //allows for up to 4 shots per second. Used for GetButtonDown.
		fireRate2 = 0.5F; //asllows for up to 2 shots per second. Used for GetButton.
		playerLives = 3;
		powerup = 0;
		shootForce = 10;
		moveDirection = Vector3.zero;
	}
	
	void Update() 
	{
		if(gameObject.tag == "Player")
		{
			if(pausedState == false)
			{
				//movement controls
				CharacterController controller = GetComponent<CharacterController>();
				moveDirection = new Vector3(0, Input.GetAxis("Vertical"), 0);
				moveDirection = transform.TransformDirection(moveDirection);
				moveDirection *= speed;
				controller.Move(moveDirection * Time.deltaTime);
				//weapon controls
				if(Input.GetButtonDown("Fire1") && Time.time > nextFire)
				{
					nextFire = Time.time + fireRate;
					PlayerFire();	
				}
				else if(Input.GetButton("Fire1") && Time.time > nextFire)
				{
					nextFire = Time.time + fireRate2;
					PlayerFire();
				}
				if(Input.GetKeyDown(KeyCode.F)) powerup = 1;
				if(Input.GetKeyDown(KeyCode.G)) powerup = 2;
			}
		}
	}
	
	void OnControllerColliderHit(ControllerColliderHit hit)
	{
		if(hit.collider.gameObject.CompareTag("Enemy"))
		{
			Destroy(hit.collider.gameObject);
			Destroy(gameObject);
			playerLives --;
			
			Instantiate(playerShip);
		}
		
		
	}
	
	IEnumerator PlayerFire()
	{
		if(powerup == 0)
		{
			shipProjectile = shipProjectile1;
		}
		else if(powerup == 1)
		{
			shipProjectile = shipProjectile2;
			yield return new WaitForSeconds(5);
			powerup = 0;
		}
		else if(powerup == 2)
		{
			shipProjectile = shipProjectile3;
			yield return new WaitForSeconds(5);
			powerup = 0;
		}
		Rigidbody clone;
		clone = Instantiate(shipProjectile, transform.position + new Vector3(1, 0, 0), transform.rotation) as Rigidbody;
		clone.rigidbody.AddForce(transform.forward * shootForce);
	}
}

Coroutines are not normal functions. They are so called generator--functions which "generates" or create a special object which is returned by the function. This object can be used to iterate through your coroutine, in other words: to execute it. This iteration is done by Unity's coroutine scheduler, but you have to "hand over" the generated object to Unity. This is done by calling StartCoroutine() with the generated object as parameter.

So far, that's how coroutines work. In your case however it makes no sense. You have a firerate of 4 shots / sec. The coroutine would wait 5 seconds (if powerup == 1 or 2) before even shoot. You will have 5*4 == 20 coroutines running at the same time. Your powerup timeout check should be done elsewhere.

Those two lines looks like debugging code:

if(Input.GetKeyDown(KeyCode.F)) powerup = 1;
if(Input.GetKeyDown(KeyCode.G)) powerup = 2;

It's better to use a function or property to set / activate a powerup.

void SetPowerUp(int aPowerUpType)
{
    powerup = aPowerUpType;
    switch (aPowerUpType)
    {
        case 1:
            StartCoroutine(ResetPowerUp(5.0f));
        break;
        case 2:
            StartCoroutine(ResetPowerUp(5.0f));
        break;
        default:
        break;
    }
}
IEnumerator ResetPowerUp(float aWaitTime)
{
    yield return new WaitForSeconds(aWaitTime);
    powerup = 0;
}

and then use it like this

if(Input.GetKeyDown(KeyCode.F)) SetPowerUp(1);
if(Input.GetKeyDown(KeyCode.G)) SetPowerUp(2);

edit ps, you might want check if you already use a powerup atm. If you start two coroutines both would set powerup to 0 after the waittime. This will propably overlap. To be able to "retrigger" the timeout you better work with timeout values which can be changed at any time.

private float m_PowerUpTimeOut = 0.0f;

void SetPowerUp(int aPowerUpType)
{
    powerup = aPowerUpType;
    switch (aPowerUpType)
    {
        case 1:
            m_PowerUpTimeOut = Time.time + 5.0f;
        break;
        case 2:
            m_PowerUpTimeOut = Time.time + 5.0f;
        break;
        default:
            m_PowerUpTimeOut = 0.0f;
        break;
    }
}

and in Update do your timeout check:

if (powerup != 0 && Time.time >= m_PowerUpTimeOut)
{
    SetPowerUp(0);
}