Search Unity

IEnumerator doesn't seem to be working.

Discussion in 'Scripting' started by TheSenpaiCode, Nov 16, 2018.

  1. TheSenpaiCode

    TheSenpaiCode

    Joined:
    Jan 21, 2016
    Posts:
    50
    Hello,

    I'm having trouble getting the buttons to appear after a few seconds. I'm running a "IEnumerator WaitForButton()". The buttons don't appear, I ran a debug ahead of the yield return new WaitForSeconds(0.5f); and it called back fine but the debug doesn't call back after the yield return new WaitForSeconds(0.5f);. Any idea why this isn't working?

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine.UI;
    4. using UnityEngine;
    5.  
    6. public class GameOverMenu : MonoBehaviour {
    7.  
    8.     public Button respawn;
    9.     public Transform respawnTarget;
    10.     public GameObject endPannel;
    11.  
    12.     public GameObject respawnButton;
    13.     public GameObject mainMenuButton;
    14.  
    15.     public bool isActive = false;
    16.  
    17.     void Start () {
    18.  
    19.     }
    20.  
    21.     void Update() {
    22.         Button btn = respawn.GetComponent<Button>();
    23.         btn.onClick.AddListener(Respawn);
    24.  
    25.         if (!respawnTarget)
    26.         {
    27.             respawnTarget = GameObject.FindWithTag("Player").transform;
    28.         }
    29.     }
    30.  
    31.        public void PlayerIsDead()
    32.         {
    33.        
    34.         if (!isActive)
    35.         {
    36.             isActive = true;
    37.             StartCoroutine(WaitForButton());
    38.         }
    39.         WaitForButton();
    40.     }
    41.  
    42.     private IEnumerator WaitForButton()
    43.     {
    44.         while (true)
    45.         {
    46.             yield return new WaitForSeconds(0.5f);
    47.             respawnButton.SetActive(true);
    48.             mainMenuButton.SetActive(true);
    49.  
    50.         }
    51.     }
    52.  
    53.     public void Respawn()
    54.     {      
    55.         respawnTarget.gameObject.SetActive(true);
    56.         FindObjectOfType<PlayerHealth>().SelectedContinue();
    57.         FindObjectOfType<SoundEffects>().PlayerIsRespawning();
    58.         FindObjectOfType<SoundEffects>().LevelMusic();
    59.         FindObjectOfType<GameManager>().CameraAlive();
    60.         endPannel.SetActive(false);
    61.         respawnButton.SetActive(false);
    62.         mainMenuButton.SetActive(false);
    63.         isActive = false;
    64.     }
    65. }
    66.  
     
  2. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    833
    I'm assuming that you have UNCHECKED the tick inside of Unity, no? Your script is dead at this point and the script may not activate. I recommend that you make sure the GameObject is CHECKED from start of your script. Then use . enabled = false; inside of a Start() function.

    Use .enabled=true; to enable the buttons rather than SetActive();

    Code (CSharp):
    1.  private IEnumerator WaitForButton()
    2.     {
    3.         while (true)
    4.         {
    5.             yield return new WaitForSeconds(0.5f);
    6.             respawnButton.gameObject.enabled=true;
    7.             mainMenuButton.gameObject.enabled=true;
    8.         }
    9.     }
    10.  
    As an example of how that would look. The SetActive() pretty much completely shuts down everything on that object; whilst the enabled simply makes it kinda hide, but everything seems to still function normally.
     
  3. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    There are multiple issues with your script:

    1) you search for the button in each frame => do it once or assign it in the inspector, which may even be better
    2) you add listeners to the button in each frame => add it only once
    2) the coroutine runs as long as the GO is active and keeps activating the buttons for no apparent reason
    4) you start the coroutine and also call it like a normal method afterwards, the latter is not really useful
     
    MisterSkitz likes this.