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

Yield Waitforseconds - Urgent

Discussion in 'Scripting' started by Mikki96, Jan 6, 2016.

  1. Mikki96

    Mikki96

    Joined:
    Oct 31, 2015
    Posts:
    2
    Hi I am making a game and want to change the ghosts' colors for 5 seconds and then change them back. I tried to use the coroutines since many tutorials suggest that. Yet when I run this code 1 and 3 display in the console right after each other but anything after the yield is not run :/

    I have the following:

    Code (CSharp):
    1.  
    2. void OnTriggerEnter(Collider other)
    3.     {
    4.             Color currentColor;
    5.             GameObject[] ghost = GameObject.FindGameObjectsWithTag ("Ghost");
    6.             foreach (GameObject g in ghost)
    7.             {
    8.                 currentColor = g.transform.GetComponent<Renderer> ().material.color;
    9.                 g.transform.GetComponent<Renderer> ().material.color = new Color (0.2f, 0.2f, 0.5f, 1.0f);
    10.                 StartCoroutine(changeColorBack (currentColor, g));
    11.                 Debug.Log ("3");
    12.             }
    13.         }
    14.     }
    15.  
    16.     IEnumerator changeColorBack(Color oldColor, GameObject g)
    17. {
    18.         Debug.Log ("1");
    19.         yield return new WaitForSeconds(5);
    20.         Debug.Log ("2");
    21.         g.transform.GetComponent<Renderer> ().material.color = oldColor;
    22. }
    23.  
     
  2. Jbarnyak

    Jbarnyak

    Joined:
    Dec 8, 2012
    Posts:
    7
    I'm not immediately sure why that wouldn't work. It might be the scope of your current color variable, but try this out:

    Code (csharp):
    1.  
    2.     IEnumerator flashColor(Renderer r)
    3.     {
    4.         Color originalColor = r.material.color;
    5.  
    6.         r.material.color = new Color(0.2f, 0.2f, 0.5f, 1.0f);
    7.  
    8.         yield return new WaitForSeconds(5);
    9.  
    10.         r.material.color = originalColor;
    11.     }
    12.  
    13.     void OnTriggerEnter(Collider other)
    14.     {
    15.         GameObject[] ghost = GameObject.FindGameObjectsWithTag("Ghost");
    16.         foreach (GameObject g in ghost)
    17.         {
    18.             StartCoroutine(flashColor(g.gameObject.GetComponent<Renderer>()));
    19.         }
    20.     }
     
  3. Mikki96

    Mikki96

    Joined:
    Oct 31, 2015
    Posts:
    2
    Hi,
    Thank so much for replying, I've been trying for hours. For some reason doing the following solved it!

    Code (CSharp):
    1.  
    2. IEnumerator OnTriggerEnter(Collider other)
    3.     {
    4.         if (other.tag == "Pacman")
    5.         {  
    6.             GhostInteraction.ghostsVulnerable = true;
    7.             Color currentColor;
    8.             GameObject[] ghost = GameObject.FindGameObjectsWithTag ("Ghost");
    9.             foreach (GameObject g in ghost)
    10.             {
    11.                 currentColor = g.transform.GetComponent<Renderer> ().material.color;
    12.                 g.transform.GetComponent<Renderer> ().material.color = new [URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=Color']Color[/URL] (0.2f, 0.2f, 0.5f, 1.0f);                                
    13.                [URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=StartCoroutine']StartCoroutine[/URL](changeColorBack (currentColor, g);
    14.                [URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=Debug']Debug[/URL].[URL='http://unity3d.com/support/documentation/ScriptReference/30_search.html?q=Log']Log[/URL] ("3");
    15.             }  
    16.         }  
    17.     }
    18.  
    19.     IEnumerator changeColorBack(Color oldColor, GameObject g){
    20.         Debug.Log ("1");
    21.         yield return new WaitForSeconds(10);
    22.         Debug.Log ("2");
    23.         g.transform.GetComponent<Renderer> ().material.color = oldColor;      
    24.     }
    25.  
     
  4. Svarr

    Svarr

    Joined:
    Dec 20, 2015
    Posts:
    22
    A wait for seconds only delays the coroutine, not the method that calls it. That is why "3" has been printed immediately after "1" and your solution works now. It's important that the lines of code that you want to delay are inside the co routine.
     
    Mycroft likes this.