Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

why is my bool not true, my bool is the canFire.

Discussion in 'Scripting' started by zafranalon, Jan 21, 2021.

  1. zafranalon

    zafranalon

    Joined:
    Dec 22, 2020
    Posts:
    9
    i have a bool that is set to true on void start and in game its false and i cant change it




    Code (CSharp):
    1. using UnityEngine.UI;
    2. using UnityEngine;
    3. using System.Collections;
    4. using UnityEngine.Animations;
    5.  
    6.  
    7.  
    8. public class gun : MonoBehaviour
    9. {
    10.  
    11.     public float damage = 10f;
    12.     public float range = 100f;
    13.     public ParticleSystem muzzleFlash;
    14.     public GameObject bulletHole;
    15.     public float impactForce = 50f;
    16.     public Camera fpsCam;
    17.     public GameObject impactEffect;
    18.     public bool Fired;
    19.     public Animator animator;
    20.     public int maxAmmo = 50;
    21.     private int currentAmmo;
    22.     public float reloadTime = 10f;
    23.     private bool isReloading = false;
    24.     public bool canFire;
    25.  
    26.     public GameObject Gun;
    27.  
    28.  
    29.     void Start()
    30.     {
    31.         currentAmmo = maxAmmo;
    32.         animator = gameObject.GetComponent<Animator>();
    33.         canFire = true;
    34.  
    35.  
    36.     }
    37.  
    38.  
    39.     void Awake()
    40.     {
    41.  
    42.     }
    43.  
    44.     void Update()
    45.     {
    46.  
    47.         if (Input.GetButtonDown("Fire1") && canFire == true)
    48.         {
    49.  
    50.             shoot();
    51.  
    52.             Fired = true;
    53.         }
    54.  
    55.         if (isReloading)
    56.             return;
    57.         if (currentAmmo > 0f)
    58.         {
    59.             canFire = true;
    60.         }
    61.  
    62.         if (currentAmmo <= 0f)
    63.         {
    64.             StartCoroutine(reload());
    65.             playReload();
    66.             canFire = false;
    67.             return;
    68.            
    69.         }
    70.         if (Input.GetButtonDown("Fire2"))
    71.         {
    72.             StartCoroutine(reload());
    73.             playReload();
    74.         }
    75.  
    76.         animator = GetComponent<Animator>();
    77.  
    78.  
    79.         if (Input.GetButtonDown("Fire2") && currentAmmo < maxAmmo)
    80.             reload();
    81.         canFire = false;
    82.  
    83.         if (currentAmmo == 0)
    84.         {
    85.             canFire = false;
    86.             reload();
    87.         }
    88.        
    89.  
    90.  
    91.  
    92.         void shoot()
    93.         {
    94.  
    95.             currentAmmo--;
    96.  
    97.             muzzleFlash.Play();
    98.  
    99.  
    100.  
    101.  
    102.             RaycastHit hit;
    103.             if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
    104.             {
    105.                 Debug.Log(hit.transform.name);
    106.                 Target target = hit.transform.GetComponent<Target>();
    107.                 if (target != null)
    108.                 {
    109.                     target.TakeDamage(damage);
    110.                 }
    111.  
    112.                 if (hit.rigidbody != null)
    113.                 {
    114.                     hit.rigidbody.AddForce(-hit.normal * impactForce);
    115.                 }
    116.  
    117.                 GameObject impactGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
    118.                 Destroy(impactGO, 2f);
    119.                 GameObject anotherOne = Instantiate(bulletHole, hit.point, Quaternion.LookRotation(hit.normal));
    120.                 Destroy(anotherOne, 2f);
    121.  
    122.                 Play();
    123.             }
    124.         }
    125.  
    126.  
    127.  
    128.          void Play()
    129.         {
    130.  
    131.             muzzleFlash.Play();
    132.         }
    133.  
    134.  
    135.         void playReload()
    136.         {
    137.  
    138.  
    139.  
    140.  
    141.  
    142.  
    143.         }
    144.  
    145.         IEnumerator reload()
    146.         {
    147.             canFire = false;
    148.             animator.SetBool("Reloading", true);
    149.             isReloading = true;
    150.             Gun.GetComponent<Animation>().Play("idle");
    151.             Debug.Log("Reloading...");
    152.             yield return new WaitForSeconds(reloadTime);
    153.             animator.SetBool("Reloading", false);
    154.             currentAmmo = maxAmmo;
    155.             animator.SetBool("Reloading", false);
    156.             isReloading = false;
    157.             animator.SetBool("Reloading", false);
    158.             canFire = true;
    159.  
    160.         }
    161.  
    162.     }
    163. }
    164.  
    165.  
    166.  
     
  2. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    You are setting canFire to false every frame on line 81
     
    zafranalon and Joe-Censored like this.
  3. zafranalon

    zafranalon

    Joined:
    Dec 22, 2020
    Posts:
    9
    thanks
     
  4. zafranalon

    zafranalon

    Joined:
    Dec 22, 2020
    Posts:
    9
    but where should i put it
     
  5. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    My guess is that you meant the canFire=false; line to be part of the above if statement. If that is the case, you need to use curly brackets:

    Code (CSharp):
    1.         if (Input.GetButtonDown("Fire2") && currentAmmo < maxAmmo)
    2. {
    3.             reload();
    4.             canFire = false;
    5. }
     
    zafranalon likes this.
  6. zafranalon

    zafranalon

    Joined:
    Dec 22, 2020
    Posts:
    9
    HOLY GOD THANKS
    can i add some delay though?
    my weapon is somewhere 356 milliseconds away from finishing reloading and its firing
     
  7. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,756
    Look up cooldown timers for this. Here are some of my feverish scribblings on the subject:

    Cooldown timers, gun bullet intervals, shot spacing, rate of fire:

    https://forum.unity.com/threads/fire-rate-issues.1026154/#post-6646297

    GunHeat (gunheat) spawning shooting rate of fire:

    https://forum.unity.com/threads/spawning-after-amount-of-time-without-spamming.1039618/#post-6729841
     
  8. zafranalon

    zafranalon

    Joined:
    Dec 22, 2020
    Posts:
    9
  9. zafranalon

    zafranalon

    Joined:
    Dec 22, 2020
    Posts:
    9
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,528
    You should delete line 79 - 87 as they serve no purpose at all besides generating garbage. Calling reload() on its own has no effect at all since it just create an IEnumerator instance which does nothing unless you pass it to StartCoroutine. However the mentioned lines are essentially just a not working duplicate of the code above those lines. When your reload coroutine is properly started it already sets canFire to false, so no reason to set it to false again. When you press Fire2 you always start the reload coroutine in line 72 regardless of the ammo state, even when already fully reloaded.

    You also should avoid using that many local methods. You defined all those methods inside your Update method. This wasn't even possible in the past but since Unity now uses a newer C# version this is possible, but really should be avoided. It makes it so much more difficult to read your code, especially when the code is longer than a single page.

    You generally have a lot redundancy in your code which makes everything much more complicated. Your canFire bool could be completely removed.

    I have posted such examples quite a couple of times in the past. When you have mutually exclusive sequencial things that requires waiting, putting all the logic into a single coroutine that keeps running makes it much simpler to implement such fireing logic.

    edit

    Code (CSharp):
    1. public class gun : MonoBehaviour
    2. {
    3.     public float damage = 10f;
    4.     public float range = 100f;
    5.     public int maxAmmo = 50;
    6.     public float reloadTime = 10f;
    7.     public float impactForce = 50f;
    8.    
    9.     private int currentAmmo;
    10.     private bool isReloading = false;
    11.    
    12.     public ParticleSystem muzzleFlash;
    13.     public GameObject bulletHole;
    14.     public Camera fpsCam;
    15.     public GameObject impactEffect;
    16.     public Animator animator;
    17.  
    18.     public GameObject Gun;
    19.     public Animation gunAnimation;
    20.    
    21.     void Start()
    22.     {
    23.         animator = GetComponent<Animator>();
    24.         gunAnimation = Gun.GetComponent<Animation>();
    25.         currentAmmo = maxAmmo;
    26.         StartCoroutine(FireLoop());
    27.     }
    28.    
    29.     IEnumerator FireLoop()
    30.     {
    31.         while(true)
    32.         {
    33.             if (currentAmmo > 0 && Input.GetButtonDown("Fire1"))
    34.             {
    35.                 shoot();
    36.             }
    37.             if (currentAmmo <= 0 || Input.GetButtonDown("Fire2"))
    38.             {
    39.                 yield return Reload();          
    40.             }
    41.             yield return null;
    42.         }
    43.     }
    44.  
    45.     void Shoot()
    46.     {
    47.         currentAmmo--;
    48.         muzzleFlash.Play();
    49.         RaycastHit hit;
    50.         if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
    51.         {
    52.             Debug.Log(hit.transform.name);
    53.             Target target = hit.transform.GetComponent<Target>();
    54.             if (target != null)
    55.             {
    56.                 target.TakeDamage(damage);
    57.             }
    58.             if (hit.rigidbody != null)
    59.             {
    60.                 hit.rigidbody.AddForce(-hit.normal * impactForce);
    61.             }
    62.             Quaternion impactRotation = Quaternion.LookRotation(hit.normal);
    63.             GameObject impactGO = Instantiate(impactEffect, hit.point, impactRotation);
    64.             Destroy(impactGO, 2f);
    65.             GameObject anotherOne = Instantiate(bulletHole, hit.point, impactRotation);
    66.             Destroy(anotherOne, 2f);
    67.         }
    68.     }
    69.    
    70.     IEnumerator Reload()
    71.     {
    72.         isReloading = true;
    73.         animator.SetBool("Reloading", true);
    74.         gunAnimation.Play("idle");
    75.         Debug.Log("Reloading...");
    76.        
    77.         yield return new WaitForSeconds(reloadTime);
    78.        
    79.         animator.SetBool("Reloading", false);
    80.         currentAmmo = maxAmmo;
    81.         isReloading = false;
    82.     }
    83. }
    Here's an example how it could be done. I removed all the noise (empty methods or pointless variables). Here we don't use Unity's Update callback but we essentially create our own update loop which can be interrupted / halted while we are reloading. So there's no need for any boolean flags as the loop will wait for the reload to complete before you can fire again.

    Note you should be more consistent with your capitalisation. Methods and classes / types should always start with a capital letter. Your TakeDamage does follow this, most methods you wrote in your script does not. Also your classname is also lower case.

    Currently you have a public gameobject reference called "Gun". You only use this to call
    GetComponent<Animation>()
    on it. You should directly link as much as possible. So I made the "gunAnimation" variable which is currently initialized in Start. However you could remove the Gun reference and the line in Start and just assign the component in the inspector by dragging it onto the gunAnimation variable.

    I also regrouped the variables so all configuration values are together and object references are below those in the inspector.
     
    Last edited: Jan 22, 2021
    zafranalon and bobisgod234 like this.