- Home /
Questions of the Coroutines
Im messing around in C# instead of Javascript. So far its been alright to transition. But One thing I noticed was the difference in co-routines. Im trying to make a gun shoot a projectile. (this is similar to my other question about how to delay a function calling) But it looks like its better to use coroutines. So the real question is, I cant call them through the update function, but if I call them through the Start or Awake function, they dont update all the time like i need them too. How do I do this?
Heres my script:
using UnityEngine;
using System.Collections;
public class Shooting : MonoBehaviour
{
//I define the projectile here.
public GameObject Gun;
public Rigidbody Bullet;
public bool canShoot = true;
public float reloadTime = 3.2F;
public int clipSize = 30;
public int clipEmptyLimit = 0;
public int clipCount = 10;
public float fireRate = 0.2F;
public float nextFire = 0.0F;
public AudioClip M4A1Shot;
// Use this for initialization
void Start ()
{
canShoot = true;
}
// Update is called once per frame
void Update()
{
//Creating the object and applying force.
if (Input.GetButton("Fire1") && Time.time > nextFire && clipSize >= 0 && clipCount > 0)
{
nextFire = Time.time + fireRate;
Rigidbody clone;
clone = Instantiate(Bullet, transform.position, Quaternion.identity) as Rigidbody;
clone.velocity = transform.TransformDirection(Vector3.forward * 1024);
audio.clip = M4A1Shot;
audio.Play();
clipSize -= 1;
}
if (clipSize == clipEmptyLimit)
{
canShoot = false;
Gun.animation.CrossFade("Reload");
clipSize = 30;
clipCount -= 1;
canShoot = true;
}
if (Input.GetKey(KeyCode.R))
{
canShoot = false;
Gun.animation.CrossFade("Reload");
clipSize = 30;
clipCount -= 1;
canShoot = true;
}
if (canShoot == false)
{
}
}
}
In Short the problem Im having is I want to wait a couple seconds after starting the reload animation so the user cant shoot until a number of seconds which will equal the length of the animation clip. Then a boolean that says they can shoot will be set back to true allowing them to shoot, and possibly have the samething work again
Answer by aldonaletto · Aug 10, 2012 at 12:29 PM
A simple way to solve this without using coroutines is as follows:
... // you don't need to repeat the reloading code: if (clipSize == clipEmptyLimit || Input.GetKey(KeyCode.R)) { Gun.animation.CrossFade("Reload"); // use nextFire to set the dead time nextFire = Time.time + reloadTime; clipSize = 30; clipCount -= 1; } ...But if you really want to use a coroutine, have a boolean flag to signal when it's reloading, so that you won't start another coroutine while the previous is running:
... // you don't need to repeat the reloading code: if (clipSize == clipEmptyLimit || Input.GetKey(KeyCode.R)) { canShoot = false; // disable shots while reloading if (!reloading){ // if not already reloading... StartCoroutine(Reload()); // start Reload } } ... }
// declare the flag variable: private bool reloading = false;
IEnumerator Reload(){ reloading = true; // reload has started Gun.animation.CrossFade("Reload"); // let the animation play during reloadTime yield return new WaitForSeconds(reloadTime); clipSize = 30; clipCount -= 1; canShoot = true; reloading = false; // reload finished }
It works I guess right now (im trying the way without the coroutines, but the amount of clips drop all the way down to the negative numbers so the gun is refusing to fire. Im guess this is becuase its in the update function. What can I do to make it only drop 1 clip from the clip amount when you reload from both ways (automatic and manual)? EDIT: I just found out to use Getbuttondown. Fail. Thanks.
The automatic reload should be done inside the "Fire1" if, and the manual reload should respect the nextFire time:
... void Update(){ if (Input.GetButton("Fire1") && Time.time > nextFire && clipSize >= 0 && clipCount > 0){ nextFire = Time.time + fireRate; Rigidbody clone; clone = Instantiate(Bullet, transform.position, Quaternion.identity) as Rigidbody; clone.velocity = transform.TransformDirection(Vector3.forward * 1024); audio.clip = $$anonymous$$4A1Shot; audio.Play(); clipSize -= 1; // check automatic reload here: if (clipSize == clipEmptyLimit) Reload(); } // check manual reload here: if (Time.time > nextFire && Input.Get$$anonymous$$ey($$anonymous$$eyCode.R)){ Reload(); } }
void Reload(){
Gun.animation.CrossFade("Reload");
// use nextFire to set the dead time
nextFire = Time.time + reloadTime;
clipSize = 30;
clipCount -= 1;
}
Your answer
Follow this Question
Related Questions
if function broken? 3 Answers
Use of boolean functions in c# 1 Answer
If function Question 1 Answer
How can I use a yeild during an udate? 1 Answer
Animation Event Bool Function? 1 Answer