Reloading ONLY when pressing "R"

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Gun : MonoBehaviour
{

Animator animator;

public enum weaponType { Shotgun, Machinegun, Burst, Launcher }; // use burst for single shot weapons like pistols / sniper rifles
public weaponType typeOfGun;

public enum LauncherType { Grenade, Rocket }; // Type of launcher
public LauncherType typeOfLauncher;

public enum BulletType { Physical, Raycast }; // physical bullets of raycasts
public BulletType typeOfBullet;


// basic weapon variables all guns have in common
// Objects, effects and tracers
public GameObject bullet = null;        // the weapons bullet object
public GameObject grenade = null;       // the grenade style round... this can also be used for arrows or similar rounds
public GameObject rocket = null;        // the rocket round
public Renderer muzzleFlash = null;     // the muzzle flash for this weapon
public Light lightFlash = null;         // the light flash for this weapon
public Transform muzzlePoint = null;    // the muzzle point of this weapon
public Transform ejectPoint = null;     // the ejection point
public Transform mountPoint = null;     // the mount point.... more for weapon swapping then anything
public Rigidbody shell = null;          // the weapons empty shell object
public GameObject gunOwner = null;      // the gun owner
public GameObject mainCamera = null;    // the player's main camera
public GameObject weaponCamera = null;  // this weapon's camera
public GameObject impactEffect = null;  // impact effect, used for raycast bullet types
public GameObject bulletHole = null;    // bullet hole for raycast bullet types

public GameObject weaponTarget = null;

//Machinegun Vars
private bool isFiring = false;          // is the machine gun firing?  used for decreasing accuracy while sustaining fire

//Shotgun Specific Vars
public int pelletsPerShot = 10;         // number of pellets per round fired for the shotgun

//Burst Specific Vars
public int roundsPerBurst = 3;          // number of rounds per burst fire
public float lagBetweenShots = 0.5f;    // time between each shot in a burst

//Launcher Specific Vars   

// basic stats
public int range = 300;                 // range for raycast bullets... bulletType = Ray
public float damage = 20.0f;            // bullet damage
public float maxPenetration = 3.0f;     // how many impacts the bullet can survive
public float fireRate = 0.5f;           // how fast the gun shoots... time between shots can be fired
public int impactForce = 50;            // how much force applied to a rigid body
public float bulletSpeed = 200.0f;      // how fast are your bullets

public int bulletsPerClip = 50;         // number of bullets in each clip
public int numberOfClips = 5;           // number of clips you start with
public int maxNumberOfClips = 10;       // maximum number of clips you can hold
private int bulletsLeft;                // bullets in the gun-- current clip
   
public float baseSpread = 1.0f;         // how accurate the weapon starts out... smaller the number the more accurate
public float maxSpread = 4.0f;          // maximum inaccuracy for the weapon
public float spreadPerSecond = 0.2f;    // if trigger held down, increase the spread of bullets
public float spread = 0.0f;             // current spread of the gun
public float decreaseSpreadPerSec = 0.5f;// amount of accuracy regained per frame when the gun isn't being fired

public float reloadTime = 1.0f;         // time it takes to reload the weapon
private bool isReloading = false;       // am I in the process of reloading
// used for tracer rendering
public int shotsFired = 0;              // shots fired since last tracer round
public int roundsPerTracer = 1;         // number of rounds per tracer

private int m_LastFrameShot = -1;       // last frame a shot was fired
private float nextFireTime = 0.0f;      // able to fire again on this frame

private float[] bulletInfo = new float[6];// all of the info sent to a fired bullet

//Network Parts ...yeah
bool localPlayer = true; //set to false // Am I a local player... or networked
string localPlayerName = "";            // what's my name
//Transform myTrans;                    // my transform


// Setting up variables as soon as a level starts
void Start()
{
    animator = GetComponent<Animator>();
    //myTrans = transform;
    bulletsLeft = bulletsPerClip; // load gun on startup
    //localPlayerName = PlayerPrefs.GetString("playerName");  // get the name of the player
}
// check whats the player is doing every frame
bool Update()
{
    if (!localPlayer)
    {
        return false;  // if not the local player.... exit function
    }
  
    // Did the user press fire.... and what kind of weapon are they using ?  ===============
    switch (typeOfGun)
    {
        case weaponType.Shotgun:
            if (Input.GetButtonDown("Fire1"))
            {
                //Debug.Log("Shotgun Fire Called");
                ShotGun_Fire();  // fire shotgun
            }
            break;
        case weaponType.Machinegun:
            if (Input.GetButton("Fire1"))
            {                   
                MachineGun_Fire();   // fire machine gun                
            }
            break;
        case weaponType.Burst:
            if (Input.GetButtonDown("Fire1"))
            {
               StartCoroutine("Burst_Fire"); // fire off a burst of rounds                  
            }
            break;

        case weaponType.Launcher:
            if (Input.GetButtonDown("Fire1"))
            {
                Launcher_Fire();
            }
            break;
    }//=========================================================================================

    if (Input.GetButton("Fire2"))
    {
        if (weaponCamera)
        {
            weaponCamera.GetComponent<Camera>().enabled = true;
            mainCamera.GetComponent<Camera>().enabled = false;
        }
    }
    else
    {
        weaponCamera.GetComponent<Camera>().enabled = false;
        mainCamera.GetComponent<Camera>().enabled = true;
    }

    //used to decrease weapon accuracy as long as the trigger remains down =====================
    if (Input.GetButtonDown("Fire1"))
    {
        isFiring = true; // fire is down, gun is firing
    }
    if (Input.GetButtonUp("Fire1"))
    {
        isFiring = false; // if fire is up... gun is not firing
    }
    if (isFiring) // if the gun is firing
    {
        spread += spreadPerSecond; // gun is less accurate with the trigger held down
    }
    else
    {
        spread -= decreaseSpreadPerSec; // gun regains accuracy when trigger is released
    }
    //===========================================================================================
    return true;
}
// update weapon flashes after checking user inout in update function
void LateUpdate()
{
    if (muzzleFlash || lightFlash)  // need to have a muzzle or light flash in order to enable or disable them
    {
        // We shot this frame, enable the muzzle flash
        if (m_LastFrameShot == Time.frameCount)
        {
            muzzleFlash.transform.localRotation = Quaternion.AngleAxis(Random.value * 57.3f, Vector3.forward);
            muzzleFlash.enabled = true;// enable the muzzle and light flashes
            lightFlash.enabled = true;
        }
        else
        {
            muzzleFlash.enabled = false; // disable the light and muzzle flashes
            lightFlash.enabled = false;
        }
    }

    if (spread >= maxSpread)
    {
        spread = maxSpread;  //if current spread is greater then max... set to max
    }
    else
    {
        if (spread <= baseSpread)
        {
            spread = baseSpread; //if current spread is less then base, set to base
        }
    }
}
// fire the machine gun
void MachineGun_Fire()
{
    if (bulletsLeft <= 0)
    {
                StartCoroutine("reload");
        return;
    }
    // If there is more than one bullet between the last and this frame
    // Reset the nextFireTime
    if (Time.time - fireRate > nextFireTime)
        nextFireTime = Time.time - Time.deltaTime;

    // Keep firing until we used up the fire time
    while (nextFireTime < Time.time)
    {
        switch (typeOfBullet)
        {
            case BulletType.Physical:
                StartCoroutine("FireOneShot");  // fire a physical bullet
                break;
            case BulletType.Raycast:
                StartCoroutine("FireOneRay");  // fire a raycast.... change to FireOneRay
                break;
            default:
                Debug.Log("error in bullet type");
                break;
        }
        shotsFired++;
        bulletsLeft--;
        nextFireTime += fireRate;
        EjectShell();
    }
   
}
// fire the burst rifle
IEnumerator Burst_Fire()
{
    int shotCounter = 0;

    if (bulletsLeft <= 0)
    {
        StartCoroutine("reload");
        yield break;//return;
    }

    // If there is more than one bullet between the last and this frame
    // Reset the nextFireTime
    if (Time.time - fireRate > nextFireTime)
        nextFireTime = Time.time - Time.deltaTime;

    // Keep firing until we used up the fire time
    while (nextFireTime < Time.time)
    {
        while (shotCounter < roundsPerBurst)
        {
            //Debug.Log(" shotCounter = " + shotCounter + ", roundsPerBurst = "+roundsPerBurst);
            switch (typeOfBullet)
            {
                case BulletType.Physical:
                    StartCoroutine("FireOneShot");  // fire a physical bullet
                    break;
                case BulletType.Raycast:
                    StartCoroutine("FireOneRay");  // fire a raycast.... change to FireOneRay
                    break;
                default:
                    Debug.Log("error in bullet type");
                    break;
            }               
            //Debug.Log("FireOneShot Called in Fire function.");
            shotCounter++;
            shotsFired++;
            bulletsLeft--; // subtract a bullet
            EjectShell();
            yield return new WaitForSeconds(lagBetweenShots);               
        }

        nextFireTime += fireRate;
    }
}
// fire the shotgun
void ShotGun_Fire()
{
    int pelletCounter = 0;  // counter used for pellets per round

    if (bulletsLeft == 0)
    {
        StartCoroutine("reload"); // if out of ammo, reload
        return;
    }

    // If there is more than one bullet between the last and this frame
    // Reset the nextFireTime
    if (Time.time - fireRate > nextFireTime)
        nextFireTime = Time.time - Time.deltaTime;

    // Keep firing until we used up the fire time
    while (nextFireTime < Time.time)
    {
        do
        {
            switch (typeOfBullet)
            {
                case BulletType.Physical:
                    StartCoroutine("FireOneShot");  // fire a physical bullet
                    break;
                case BulletType.Raycast:
                    StartCoroutine("FireOneRay");  // fire a raycast.... change to FireOneRay
                    break;
                default:
                    Debug.Log("error in bullet type");
                    break;
            }
            pelletCounter++; // add another pellet
            shotsFired++; // another shot was fired               
        } while (pelletCounter < pelletsPerShot); // if number of pellets fired is less then pellets per round... fire more pellets
        EjectShell(); // eject 1 shell
        nextFireTime += fireRate;  // can fire another shot in "firerate" number of frames
        bulletsLeft--; // subtract a bullet
    }
}
// fire your launcher
void Launcher_Fire()
{
    if (bulletsLeft == 0)
    {
        StartCoroutine("reload"); // if out of ammo, reload
        return;
    }

    // If there is more than one bullet between the last and this frame
    // Reset the nextFireTime
    if (Time.time - fireRate > nextFireTime)
        nextFireTime = Time.time - Time.deltaTime;

    // Keep firing until we used up the fire time
    while (nextFireTime < Time.time)
    {
        StartCoroutine("FireOneProjectile"); // fire 1 round               
        nextFireTime += fireRate;  // can fire another shot in "firerate" number of frames
        bulletsLeft--; // subtract a bullet
    }
}
// Create and fire a bullet
IEnumerator FireOneShot()
{
    Vector3 position = muzzlePoint.position; // position to spawn bullet is at the muzzle point of the gun      

    // set the gun's info into an array to send to the bullet
    bulletInfo[0] = damage;
    bulletInfo[1] = impactForce;
    bulletInfo[2] = maxPenetration;
    bulletInfo[3] = maxSpread;
    bulletInfo[4] = spread;
    bulletInfo[5] = bulletSpeed;

    //bullet info is set up in start function
    GameObject newBullet = Instantiate(bullet, position, transform.parent.rotation) as GameObject; // create a bullet
    newBullet.SendMessageUpwards("SetUp", bulletInfo); // send the gun's info to the bullet
    newBullet.GetComponent<Bullet>().Owner = gunOwner; // owner of the bullet is this gun's owner object

    if (!(typeOfGun == weaponType.Launcher))
    {
        if (shotsFired >= roundsPerTracer) // tracer round every so many rounds fired... is there a tracer this round fired?
        {
            newBullet.GetComponent<Renderer>().enabled = true; // turn on tracer effect
            shotsFired = 0;                    // reset tracer counter
        }
        else
        {
            newBullet.GetComponent<Renderer>().enabled = false; // turn off tracer effect
        }

        if (GetComponent<AudioSource>())
        {
            GetComponent<AudioSource>().Play();  // if there is a gun shot sound....play it
        }
    }      

    if ((bulletsLeft == 0))
    {
        StartCoroutine("reload");  // if out of bullets.... reload
        yield break;
    }
   
    // Register that we shot this frame,
    // so that the LateUpdate function enabled the muzzleflash renderer for one frame
    m_LastFrameShot = Time.frameCount;
}
// Create and Fire a raycast
IEnumerator FireOneRay()
{

    string[] Info = new string[2];
    int hitCount = 0;
    bool tracerWasFired = false;
    Vector3 position = muzzlePoint.position; // position to spawn bullet is at the muzzle point of the gun
    Vector3 direction = muzzlePoint.TransformDirection(Random.Range(-maxSpread, maxSpread) * spread, Random.Range(-maxSpread, maxSpread) * spread, 1);
    Vector3 dir = (weaponTarget.transform.position - position) + direction;

    // set the gun's info into an array to send to the bullet
    bulletInfo[0] = damage;
    bulletInfo[1] = impactForce;
    bulletInfo[2] = maxPenetration;
    bulletInfo[3] = maxSpread;
    bulletInfo[4] = spread;
    bulletInfo[5] = bulletSpeed;

    if (shotsFired >= roundsPerTracer)
    {
        FireOneTracer(bulletInfo);
        shotsFired = 0;
        tracerWasFired = true;
    }        
   
    RaycastHit[] hits = Physics.RaycastAll(position , dir, range);

    for (int i = 0; i < hits.Length; i++)
    {
        if (hitCount >= maxPenetration)
        {
            yield break;
        }          

        RaycastHit hit = hits[i];
        //Debug.Log( "Bullet hit " + hit.collider.gameObject.name + " at " + hit.point.ToString() );

        // notify hit
        if (!tracerWasFired)
        { // tracers are set to show impact effects... we dont want to show more then 1 per bullet fired
            ShowHits(hit); // show impacts effects if no tracer was fired this round
        }

        Info[0] = localPlayerName;
        Info[1] = damage.ToString();
        hit.collider.SendMessageUpwards("ImHit", Info, SendMessageOptions.DontRequireReceiver);
        // Debug.Log("if " + hitCount + " > " + maxHits + " then destroy bullet...");   
        hitCount++;
    }       
}
// Create and Fire 1 launcher projectile
IEnumerator FireOneProjectile()
{
    Vector3 position = muzzlePoint.position; // position to spawn rocket / grenade is at the muzzle point of the gun

    bulletInfo[0] = damage;
    bulletInfo[1] = impactForce;
    bulletInfo[2] = maxPenetration;
    bulletInfo[3] = maxSpread;
    bulletInfo[4] = spread;
    bulletInfo[5] = bulletSpeed;

    switch (typeOfLauncher)
    {
        case LauncherType.Grenade:
            GameObject newNoobTube = Instantiate(grenade, position, transform.parent.rotation) as GameObject;
            newNoobTube.SendMessageUpwards("SetUp", bulletInfo);
            break;
        case LauncherType.Rocket:
            GameObject newRocket = Instantiate(rocket, position, transform.parent.rotation) as GameObject;
            newRocket.SendMessageUpwards("SetUp", bulletInfo);
            break;
        default:
            Debug.Log("invalid launcher type.... default fired");
            break;
    }

    if (GetComponent<AudioSource>())
    {
        GetComponent<AudioSource>().Play();  // if there is a gun shot sound....play it
    }

    if ((bulletsLeft == 0))
    {
        StartCoroutine("reload");  // if out of bullets.... reload
        yield break;
    }

    // Register that we shot this frame,
    // so that the LateUpdate function enabled the muzzleflash renderer for one frame
    m_LastFrameShot = Time.frameCount;

}
// create and "fire" an empty shell
void EjectShell()
{
    Vector3 position = ejectPoint.position; // ejectile spawn point at gun's ejection point
   
    if (shell)
    {
        Rigidbody newShell = Instantiate(shell, position, transform.parent.rotation) as Rigidbody; // create empty shell
        //give ejectile a slightly random ejection velocity and direction
        newShell.velocity = transform.TransformDirection(Random.Range(-2, 2) - 3.0f, Random.Range(-1, 2) + 3.0f, -Random.Range(-2, 2) + 1.0f);
    }
}
// tracer rounds for raycast bullets
void FireOneTracer(float[] info)
{
    Vector3 position = muzzlePoint.position;
    GameObject newTracer = Instantiate(bullet, position, transform.parent.rotation) as GameObject; // create a bullet
    newTracer.SendMessageUpwards("SetUp", info); // send the gun's info to the bullet
    newTracer.SendMessageUpwards("SetTracer");  // tell the bullet it is only a tracer
}
//effects for raycast bullets
void ShowHits(RaycastHit hit)
{
    switch (hit.transform.tag)
    {
        case "bullet":
            // do nothing if 2 bullets collide
            break;
        case "Player":
            // add blood effect
            break;
        case "wood":
            // add wood impact effects
            break;
        case "stone":
            // add stone impact effect
            break;
        case "ground":
            // add dirt or ground  impact effect
            break;
        default: // default impact effect and bullet hole
            Instantiate(impactEffect, hit.point + 0.1f * hit.normal, Quaternion.FromToRotation(Vector3.up, hit.normal));
            GameObject newBulletHole = Instantiate(bulletHole, hit.point, Quaternion.FromToRotation(Vector3.up, hit.normal)) as GameObject;
            newBulletHole.transform.parent = hit.transform;
            break;
    }
}
// reload your weapon
IEnumerator reload()
{
    if (isReloading)
    {
        yield break; // if already reloading... exit and wait till reload is finished
    }

    {
        {
        isReloading = true; // we are now reloading
        numberOfClips--; // take away a clip
        yield return new WaitForSeconds(reloadTime); // wait for set reload time
        bulletsLeft = bulletsPerClip; // fill up the gun
        }
    }

    isReloading = false; // done reloading
}

}


*It's a script i got from Nova i believe his name was.*
*So my problem here is, the gun auto reloads, i want to make it only reload when i press "R".*
*I tried adding if(Input.GetKeyDown("r")) Both in the IEunmerator reload AND Machine gun fire under the Bulletsleft >= 0; Either, it just doesn't reload, or gives me unlimited ammo for some reason :/*
*I really don't know what to do :| Maybe it's an obvious/easy solution, but i don't know. I barely know anything about scripting. I know a little of the basics but yeah, other than that, nope :/*
*Any help would be appreciated :smile:*
*BTW I'm really sorry about the long script, but it's easier if you have a whole view of the script i suppose :)*

[code ][/code ] tags… there is a sticky at the top of the scripting section on them.

Oops, sry got it now :slight_smile:

Use something like

while (Input.GetKeyDown(KeyCode.R)
{
   // do reload stuff
}

If the key isn’t down then it won’t continue the Coroutine.

I think part of the problem is even though this code has good comments it’s way too complicated for a beginner, I’m a sort-of beginner now and struggling to read it all clearly.

Found this after glancing around youtube, you may find better ones out there, but what they do is give you very basic scripts to work from and you’ll know what everything does then add on from there. Or move onto more complicated scripts.

Keep things simple and work your way up, if you can’t do that, then get somebody else to do the programming for you.

What you tried with GetKeyDown should be correct. But you should be using KeyCode.R instead of “r”. GetButtonDown(“String”) is for Buttons set up in the Input menu. You’d want to do if (bulletsLeft <= 0 && Input.GetKeyDown(KeyCode.R))
And do listen to Lethn’s advice and do some tutorials before tackling complex scripts you can’t understand :slight_smile:

Currently looking at camera scripting and getting a headache -_- :smile:

I’ve done camera scripting before haha is there anything you don’t understand?

I posted a thread up that’s gone to the second page now if you’d be kind enough to look, it shouldn’t be a difficult problem, it involved getting a camera position I think, hope this doesn’t count as hijacking a thread.

It got unlimited ammo again, it reloads constantly :confused:
And i didn’t even press R, this is so weird :expressionless:

Like I said, I’d start afresh if you’re having tons of problems, go from the tutorial I posted and see how that works out for you.

Yeah, but all i need is for it too not reload automatically, and only when i press “R”, but if this isn’t gonna work anytime soon, i’ll do that tutorial. Because so far this is a pain in the arse man.

It’s a very complicated script, as for reloading, it shouldn’t be anything more than a couple of variables at most which is why you’re having such a hard time, because you’re having to dig through all that code to find one little function, I know the feeling.

The script is complex not because it’s advanced, but because it is trying to do a lot of things. It’s a dozen different weapons, and each of them behaves differently. It should really be several scripts.

Structure aside, the easiest way to do this would just be to put each call to StartCoroutine(Reload()); inside an if statement. Like this.

if (Input.GetKeyDown(KeyCode.R)){
    StartCoroutine(Reload());
}

Still reloads constantly :confused: I really don’t get it, what kind of sorcery is this?

Somebody please have an answer for this i’m friggin dying here, i can’t figure this out…
When i have it like this
if(bulletsLeft <=0), its fine(except it auto reloads), but as soon as i change it too
if(bulletsLeft <=0 && Input.GetKeyDown(KeyCode.R))
Then it calls the reload function, but ignores the yield returnnew WaitForSeconds thing…AND I DIDN’T EVEN PRESS “R”:expressionless:
So it insta reloads, aka unlimited ammo nonstop shooting.

It’s so annoying…