1
\$\begingroup\$

Hello I am very new to Unity and am trying to make a shooting game in which when the space key is pressed down the gun charges then shoots. I want it to wait for 0.3 seconds before the gun fires off because I want an effect to happen with a particle system(I confused animation with effect in the first post). Also the problem the script has is that the bullet would not fire at all when the space is pressed. Here is the scripts I wrote:

 void Start()
 {
     StartCoroutine("Shoot",0.3f);
 }

 IEnumerator Shoot()
 {
     yield return new WaitForSeconds (0.3f);
     Bam ();
 }

 void Bam()
 {
     transform.Translate (0, 0, 12);
 }

 void Update () 
 {        
     if (Input.GetKey (KeyCode.Space))
         Shoot();
 }
\$\endgroup\$
  • \$\begingroup\$ What seems to be problem with your current code? \$\endgroup\$ – Sourav Paul Jul 12 '16 at 12:39
  • \$\begingroup\$ If I had to guess, I would say it's failing to compile because they're trying to pass through a float 0.3f to a Coroutine that doesn't have any arguments. In Start(), just put "StartCoroutine(Shoot())", and it should be fine. \$\endgroup\$ – DisturbedNeo Jul 12 '16 at 16:48
0
\$\begingroup\$

It's been a while since I used Unity, but I don't think you need the Coroutine. I'd just use a private variable instead.

private const float timeToCharge = 0.3f;
private float chargeTimer = 0.0f;

private void Update()
{
    if (Input.GetKey(KeyCode.Space))
    {
        chargeTimer += Time.deltaTime;
        if (chargeTimer >= timeToCharge)
        {
            chargeTimer -= timeToCharge;
            Bam();
        }
    }
    else if (Input.GetKeyUp(KeyCode.Space))
    {
        chargeTimer = 0.0f;
    }
}

Note that if you want the player to only be able to fire once when having charged the weapon you'll need to add a boolean to keep track of that and then check the condition of that boolean in both the if-statements inside Update().

private bool weaponFired = false;
...
if (!weaponFired && Input.GetKey(KeyCode.Space))
{
    chargeTimer += timeToCharge;
    if (chargeTimer >= timeToCharge)
    {
        Bam();
        weaponFired = true;
    }
}
else if (weaponFired && Input.GetKeyUp(KeyCode.Space))
{
    chargeTimer = 0.0f;
    weaponFired = false;
}

Note that you don't need to subtract timeToCharge from the chargeTimer if the player only is allowed to fire once per click.

\$\endgroup\$
0
\$\begingroup\$

You can do something different.

You could use Unity's animation events system. You can find it in the Animation tab (the bookmark with plus sign on it). Actually you can just check this Unity manual page.

In your update method (better cache your animator link in start/awake):

void Update () 
{        
    if (Input.GetKey (KeyCode.Space)) {
        Animator animator = GetComponent<Animator>();
        animator.Play("ShootStateName");
    }
}

Then you create new method and there you put projectile's spawn and move code. This new method you link in the animator's events system as shown in the manual.

The good thing of this approach is that, if you later decide to modify your charge/shoot animation, you wouldn't need to modify your code.

\$\endgroup\$
0
\$\begingroup\$

it is better to run your animation on button press something like this

void Update () 
 {        
     if (Input.GetKey (KeyCode.Space))
         //Play your animation
 }

and then check on update that if your animation have finished then shoot

bool animationClipPlaying = false;

    void Update()
    {
     if (GetComponent<Animation>().IsPlaying(clipNameCompare))
     {
         //as animation start to play true the bool
         animationClipPlaying = true; //true this for comparsion
     }
     //if animation is not playing and the bool is true then, animation finished
     else if (!GetComponent<Animation>().IsPlaying(clipNameCompare) && animationClipPlaying)
     {
         //shoot the fire- your function of fire
          Bam ();
         //False so that this condition run only once
         aanimationClipPlaying = false; 
     }
}
\$\endgroup\$
  • \$\begingroup\$ Isn't it better to cache the result of GetComponent<Animation> instead of (potentially) calling it multiple times? Can possibly even be cached when the game object is initialized, during Awake or Start? \$\endgroup\$ – user1323245 Jul 14 '16 at 13:57
  • \$\begingroup\$ obvioulsly it is right efficient solution but i dont want to add any complexity for the user. it seems that he is new anyhow you can update the answer. Thanks \$\endgroup\$ – Muhammad Faizan Khan Jul 15 '16 at 5:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.