Search Unity

Using IEnumerator to wait to continue script til animation finishes

Discussion in 'Scripting' started by firestorm185, Jan 25, 2021.

  1. firestorm185

    firestorm185

    Joined:
    Sep 23, 2014
    Posts:
    24
    I have a UI that scales in and out on a button press, and I'm using an IEnumerator via script to wait until the animation finishes to actually disable the UI. Problem is, the script I have right now closes the menu, and then I have to double press the button to reopen the menu, where the first time I open it it's a single press. Anyone know what I'm messing up on?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.SceneManagement;
    5. using UnityEngine.XR.Interaction.Toolkit;
    6.  
    7. public class WatchMenuScript : MonoBehaviour
    8. {
    9.  
    10.     public Collider WatchBox; // The Collider Used to determine whether or not to open the menu.
    11.     public GameObject Menu; // The UI Canvas that is opened or closed when the watch is clicked.
    12.     public GameObject InteractHand; // The Manually set hand that clicks the watch (opposite hand of the arm the watch is on)
    13.     public GameObject Sound_Device; // The GameObject responsible for creating Menu sounds.
    14.     AudioSource WatchAudio; // The Non-editable variable that contains the Audio_Source of the Sound_Device GameObject.
    15.     public List<AudioClip> MenuSounds; // The list of sound clips for closing and opening the Menu. The first clip is the opening sound, and the second clip is the closing sound.
    16.  
    17.     bool watchClicked = false; // A bool that ensures the menu toggles only once per watch collision.
    18.     bool MenuToggle; // The boolean variable that tracks whether or not the Menu Canvas is enabled.
    19.    
    20.  
    21.     Animator MenuAnimator;
    22.  
    23.     // Start is called before the first frame update
    24.     void Start()
    25.     {
    26.       WatchAudio = Sound_Device.GetComponent<AudioSource>(); // Automatically sets WatchAudio to the AudioSource of Sound_Device.
    27.         MenuAnimator = Menu.GetComponent<Animator>();
    28.     }
    29.  
    30.  
    31.  
    32.     private void OnTriggerEnter(Collider WatchBox)
    33.     {
    34.  
    35.         if (MenuToggle == true && watchClicked == false) // If this is the first update that the trigger has collided, and the menu is on, it's turned off and variable values are reset.
    36.         {
    37.            
    38.  
    39.             WatchAudio.clip = MenuSounds[1];
    40.             MenuAnimator.SetBool("MenuOpen", false);
    41.             WatchAudio.Play();
    42.             StartCoroutine(playAnim());
    43.  
    44.         }
    45.         else if (MenuToggle == false && watchClicked == false) // if this is the first update that the trigger has collided, and the menu is off, the menu is turned on.
    46.         {
    47.  
    48.             Menu.SetActive(true);
    49.             MenuToggle = true;
    50.  
    51.             WatchAudio.clip = MenuSounds[0];
    52.             MenuAnimator.SetBool("MenuOpen", true);
    53.             WatchAudio.Play();
    54.  
    55.  
    56.         }
    57.  
    58.         watchClicked = true; // after the if statements, the watchClicked variable is enabled so the if statements only play out once.
    59.      
    60.         //Both Hand Controllers Vibrate via the two lines below.
    61.         InteractHand.GetComponent<RoboHand_Presence>().vibrateRightController();
    62.         InteractHand.GetComponent<RoboHand_Presence>().vibrateLeftController();
    63.  
    64.     }
    65.  
    66.     private void OnTriggerExit(Collider WatchBox) // When the trigger does not collide with the pointer finger, the watchClicked variable returns to false, so the if statements above can fire again.vi
    67.     {
    68.         watchClicked = false;
    69.        
    70.            
    71.            
    72.        
    73.     }
    74.  
    75.     IEnumerator playAnim()
    76.     {
    77.  
    78.         bool isFinishedAnim = false;
    79.         int animLayer = 0;
    80.  
    81.  
    82.         //Wait until Animator is done playing
    83.         while (MenuAnimator.GetCurrentAnimatorStateInfo(0).IsName("Close_Menu") &&
    84.         MenuAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime < 1.0f)
    85.         {
    86.             //Wait every frame until animation has finished
    87.             yield return null;
    88.         }
    89.         //Done playing. Do something below!
    90.         isFinishedAnim = true;
    91.  
    92.         if (MenuToggle == true) // If this is the first update that the trigger has collided, and the menu is on, it's turned off and variable values are reset.
    93.         {
    94.  
    95.  
    96.  
    97.             if (MenuAnimator.GetCurrentAnimatorStateInfo(0).IsName("Close_Menu"))
    98.             {
    99.                 Menu.SetActive(false);
    100.                 MenuToggle = false;
    101.                
    102.             }
    103.  
    104.  
    105.  
    106.         }
    107.  
    108.     }
    109.  
    110. }
    111.  
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
    Probably some state not quite reset properly in the above code. But first isolate if the calls are actually happening from the button. ALSO remember if you click outside the Unity game window, the first click back is ignored.

    To help gain more insight into your problem, I recommend liberally sprinkling Debug.Log() statements through your code to display information in realtime.

    Doing this should help you answer these types of questions:

    - is this code even running? which parts are running? how often does it run?
    - what are the values of the variables involved? Are they initialized?

    Knowing this information will help you reason about the behavior you are seeing.
     
  3. firestorm185

    firestorm185

    Joined:
    Sep 23, 2014
    Posts:
    24
    Thanks for the suggestions! I eventually got it working in another way that I don't think had to use IEnums but I'll keep that in mind for next time!