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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

c# yield updating more than once

Discussion in 'Scripting' started by GForce007, Aug 10, 2016.

  1. GForce007

    GForce007

    Joined:
    May 22, 2015
    Posts:
    27
    Hi Everyone,

    I have a issue with my yielding script. Every time I hit the mouse button once, my animation plays perfectly, ammo get decreased perfectly etc. But when I hold the mouse button down, everything still works well, except my ammo will decrease in increments of two's and one's, never completely consistent.

    It doesn't matter if I decrease the ammo before or after the yeild.
    Can anyone please check if I'm doing something wrong?

    Thanx.

    Code (csharp):
    1.  
    2.  
    3.     IEnumerator PistolShoot()
    4.     {
    5.         if (bulletsInMag == 0 || pistolAnim.GetBool("reload") == true)
    6.         {
    7.             pistolAnim.SetBool("shoot", false);
    8.             yield break;
    9.         }
    10.  
    11.         pistolAnim.SetBool("shoot", true);
    12.         gunSounds[(int)PistolSounds.PistolShoot].Play();
    13.  
    14.         Debug.Log("AMMO " + bulletsInMag);
    15.         bulletsInMag -= 1;
    16.  
    17.         yield return new WaitForSeconds(shootAgainTimer);
    18.         pistolAnim.SetBool("shoot", false);
    19.  
    20.         yield return new WaitForEndOfFrame();
    21.     }
    22.  
    23.     IEnumerator PistolReload()
    24.     {
    25.         yield return new WaitForSeconds(reloadTimer);
    26.  
    27.         gunSounds[(int)PistolSounds.PistolRelease].Play();
    28.         pistolAnim.SetBool("reload", false);
    29.         bulletsInMag = magazineSize;
    30.  
    31.         yield break;
    32.     }
    33.  
    34.     void PistolEvents()
    35.     {
    36.        if (Input.GetMouseButton(0) && pistolAnim.GetBool("shoot") == false && pistolAnim.GetBool("reload") == false && bulletsInMag > 0)
    37.        {
    38.             StartCoroutine("PistolShoot");
    39.        }
    40.        if (bulletsInMag == 0 && pistolAnim.GetBool("shoot") == false && pistolAnim.GetBool("reload") == false ||
    41.            Input.GetKey("r") && bulletsInMag < magazineSize && pistolAnim.GetBool("shoot") == false && pistolAnim.GetBool("reload") == false)
    42.        {
    43.             pistolAnim.SetBool("reload", true);
    44.             gunSounds[(int)PistolSounds.PistolMag].Play();
    45.  
    46.             StartCoroutine("PistolReload");
    47.        }
    48.     }
    49.  
    50.  
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    sounds a lot like you're getting into a situation where you've got more than one coroutine running at the same time.

    However the only place I can see where your conditionals are all true but the coroutine hasn't exited yet is the final yield of the PistolShoot function... is there anything else that updates "pistolAnim.shoot" (animation event maybe?)?
     
  3. GForce007

    GForce007

    Joined:
    May 22, 2015
    Posts:
    27
    Currently only the shoot and reload routines, nothing else.
    There's also no events in the animations.

    Even the gun sound keeps playing??
     
  4. GForce007

    GForce007

    Joined:
    May 22, 2015
    Posts:
    27
    OK, got it sorted, but not how I'd like, but it works.
    If anyone has a different cleaner approach I can use, I will really appreciate it.

    And thank you LeftyRighty for your reply, I appreciate the help.

    Code (csharp):
    1.  
    2.  
    3.     IEnumerator PistolShoot()
    4.     {
    5.         if (bulletsInMag == 0 || pistolAnim.GetBool("reload") == true)
    6.         {
    7.             pistolAnim.SetBool("shoot", false);
    8.             yield break;
    9.         }
    10.  
    11.         if (shooting == false)
    12.         {
    13.             pistolAnim.SetBool("shoot", true);
    14.             gunSounds[(int)PistolSounds.PistolShoot].Play();
    15.             gunFlash.enabled = true;
    16.  
    17.             Debug.Log("AMMO " + bulletsInMag);
    18.             bulletsInMag -= 1;
    19.  
    20.             shooting = true;
    21.         }
    22.         if (shooting == true)
    23.         {
    24.             yield return new WaitForSeconds(shootAgainTimer);
    25.             pistolAnim.SetBool("shoot", false);
    26.             gunFlash.enabled = false;
    27.  
    28.             yield return new WaitForSeconds(shootAgainTimer);
    29.             shooting = false;
    30.             yield break;
    31.         }
    32.     }
    33.  
    34.     IEnumerator PistolReload()
    35.     {
    36.         yield return new WaitForSeconds(reloadTimer);
    37.  
    38.         gunSounds[(int)PistolSounds.PistolRelease].Play();
    39.         pistolAnim.SetBool("reload", false);
    40.         bulletsInMag = magazineSize;
    41.  
    42.         yield break;
    43.     }
    44.  
    45.     void PistolEvents()
    46.     {
    47.        if (Input.GetMouseButton(0) && pistolAnim.GetBool("shoot") == false && pistolAnim.GetBool("reload") == false && bulletsInMag > 0 && shooting == false)
    48.        {
    49.             StartCoroutine("PistolShoot");
    50.        }
    51.        if (bulletsInMag == 0 && pistolAnim.GetBool("shoot") == false && pistolAnim.GetBool("reload") == false ||
    52.            Input.GetKey("r") && bulletsInMag < magazineSize && pistolAnim.GetBool("shoot") == false && pistolAnim.GetBool("reload") == false)
    53.        {
    54.             pistolAnim.SetBool("reload", true);
    55.             gunSounds[(int)PistolSounds.PistolMag].Play();
    56.  
    57.             StartCoroutine("PistolReload");
    58.        }
    59.     }
    60.  
    61.  
     
  5. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    do you prefer doing things through scripting? because there is another approach which puts the logic more into the animator setup, the script is then reduced to passing the input into the animator triggers (not bools) and the additional effects (sound, particles etc.) are handled through "animation events". Some dislike it because it can make things more difficult to see what is going on because it's spread out in the animator not in a single script.
     
  6. GForce007

    GForce007

    Joined:
    May 22, 2015
    Posts:
    27
    I actually do feel that animations should stay within the animator and scripting should be used for the game logic. Hate creating all these variables. I tried using the events system in the animator with no real results.

    But honestly haven't given it a whole lot of effort.
     
  7. GForce007

    GForce007

    Joined:
    May 22, 2015
    Posts:
    27
    So I played around with the events in the animator and it works brilliantly, just need to be placed in the right frame of the animation and viola!!!

    Here's the code and you can clearly see the difference in the amount of code and NO MORE TIMERS!!! Loving it!!!
    Thanx LeftyRighty!!

    Code (csharp):
    1.  
    2.     // this function is only called by the animator in the shoot animation
    3.     void PistolShootEndframe()
    4.     {
    5.         pistolAnim.SetBool("shoot", false);
    6.         bulletsInMag -= 1;
    7.         pistolAnim.SetInteger("bulletsInMag", bulletsInMag);
    8.     }
    9.  
    10.     // This function is only called by the animator in the reload animation
    11.     void PistolReloadEndFrame()
    12.     {
    13.         bulletsInMag = magazineSize;
    14.         pistolAnim.SetInteger("bulletsInMag", bulletsInMag);
    15.         pistolAnim.SetBool("reload", false);
    16.     }
    17.  
    18.     void PistolEvents()
    19.     {
    20.        if (Input.GetMouseButton(0) && pistolAnim.GetBool("shoot") == false)
    21.        {
    22.             if (bulletsInMag > 0)
    23.             {
    24.                 pistolAnim.SetBool("shoot", true);
    25.             }
    26.             if (bulletsInMag == 0 && pistolAnim.GetBool("shoot") == false)
    27.             {
    28.                 pistolAnim.SetBool("reload", true);
    29.             }
    30.         }
    31.  
    32.        if (Input.GetKey("r") && bulletsInMag < magazineSize)
    33.        {
    34.             pistolAnim.SetBool("reload", true);
    35.        }
    36.     }
    37.  
     
  8. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148