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

Wait/Delay Question

Discussion in 'Scripting' started by Fyurien, Aug 22, 2015.

  1. Fyurien

    Fyurien

    Joined:
    Aug 16, 2015
    Posts:
    20
    Hello,

    I'm looking to place a wait/delay in the middle of a block of code. The code specifically is meant to turn a light on or off. Actually to be clear is meant to enable/disable a prefab. In this case a light. Here is the code.

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4.  
    5. public class lightSwitch : MonoBehaviour {
    6.     static bool  activate = false;
    7.     public GameObject spotLight;
    8.  
    9.  
    10.     void  OnTriggerEnter ( Collider other  )
    11.     {
    12.      
    13.         if (other.gameObject.tag == "Activate")
    14.         {
    15.          
    16.             if(!activate)
    17.             {
    18.  
    19.                 activate = true;
    20.                 spotLight.SetActive(true);
    21.                 //yield WaitForSeconds(1f);
    22.             }
    23.  
    24.             else
    25.             {
    26.  
    27.                 activate = false;
    28.                 spotLight.SetActive(false);
    29.             }
    30.  
    31.          
    32.         }
    33.  
    34.  
    35.     }
    36.  
    37.  
    38. }
    The code itself is pretty simple, but figuring out how to put in a delay wait is not. The reason I want to do this is because when I do activate the light switch it turns on just fine. But when I try to turn it off it flickers on and off very quickly. So I thought a short 1 second delay ought to remove the on/off/on/off flicker.

    I looked at using WaitForSeconds using StartCoroutines and IEnumerator, but it seems to not work with OnTriggerEnter.

    Anyway, any advice from someone more knowledgeable than me would be very appreciated.

    Thank you
     
  2. Duugu

    Duugu

    Joined:
    May 23, 2015
    Posts:
    241
    You can't "pause" a function via a coroutine. That's not how coroutines are working.

    I would add a second flag and the OnTriggerLeaving event (or whatever the exact name is). Then set the second flag to true on OnTriggerLeaving and do the OnTriggerEnter stuff only if the second flag is true.
     
    Last edited: Aug 22, 2015
    Fyurien likes this.
  3. lineupthesky

    lineupthesky

    Joined:
    Jan 31, 2015
    Posts:
    92
    Well logic for this kind of situations is to add a delay as you mentioned, and use a control boolean in order to control the delay. So, best workout for adding delays is using Coroutines, and you can change your script like this :

    Code (CSharp):
    1. using UnityEngine;
    2.     using System.Collections;
    3.  
    4.  
    5.     public class lightSwitch : MonoBehaviour {
    6.         static bool  activate = false;
    7.         public GameObject spotLight;
    8.         private bool b_CanActivate = true;
    9.    
    10.         void  OnTriggerEnter ( Collider other  )
    11.         {
    12.        
    13.             if (other.gameObject.tag == "Activate")
    14.             {
    15.            
    16.                 if(!activate && b_CanActivate)
    17.                 {
    18.                     b_CanActivate = false;
    19.                     activate = true;
    20.                     spotLight.SetActive(true);
    21.                     StartCoroutine(Delay (1));
    22.                 }
    23.            
    24.                 else if(activate && b_CanActivate)
    25.                 {
    26.                     b_CanActivate = false;
    27.                     activate = false;
    28.                     spotLight.SetActive(false);
    29.                     StartCoroutine(Delay (1));
    30.  
    31.                 }
    32.            
    33.            
    34.             }
    35.        
    36.        
    37.         }
    38.  
    39.         IEnumerator Delay(float time)
    40.         {
    41.             yield return new WaitForSeconds(time);
    42.             b_CanActivate = true;
    43.         }
    44.    
    45.    
    46.     }
    47.  
    48.  
    49.  
    What I did was to add a "b_CanActivate" boolean, if this is false there is no way that the light will be enabled / disabled. Each time light has changed it's status, it makes this boolean false, preventing it from changing again until the Delay coroutine is called and finished waiting. By the way, you can use yield waitforseconds in js like that, but not in cs, it has nothing to do with using it on Trigger functions, the way you were using was wrong. The correct usage is like I've showed above.

    Cheers,
    Inan
     
    Fyurien likes this.
  4. Fyurien

    Fyurien

    Joined:
    Aug 16, 2015
    Posts:
    20
    Thank you for your suggestion!
     
  5. Fyurien

    Fyurien

    Joined:
    Aug 16, 2015
    Posts:
    20
    Ok that is a really clever way to do it. So create b_CanActivate boolean, then wait for it to be set to true, which allows the rest of the script to run. Awesome!

    Thank you so much Inan!
     
  6. Fyurien

    Fyurien

    Joined:
    Aug 16, 2015
    Posts:
    20
    Wohooo! It works!!!! THANK YOU THANK YOU THANK YOU!
     
  7. lineupthesky

    lineupthesky

    Joined:
    Jan 31, 2015
    Posts:
    92
    No problem dude, just keep this kind of logic in your mind, you will use a lot when programming gameplay parts, have a nice day!
     
    Fyurien likes this.
  8. Fyurien

    Fyurien

    Joined:
    Aug 16, 2015
    Posts:
    20
    Im actually learning C# right now, so I'm slowly learning the language! Thank you again!
     
    lineupthesky likes this.