Search Unity

another noob question: callback functions? SOLVED

Discussion in 'Scripting' started by Kentyman, Aug 6, 2009.

  1. Kentyman

    Kentyman

    Joined:
    Jul 14, 2009
    Posts:
    28
    hi!

    I want to create a timer function in c# to do some timing stuff :) To do that I would like to create a method like this:

    Code (csharp):
    1. void SetTimer(float TimeToWait, Object(??) CallbackFunction)
    and then use it like so:

    Code (csharp):
    1. SetTimer(3.0f, TheMethodThatNeedsToBeCalledWhenTheTimerIsFinished);
    2.  
    3. void TheMethodThatNeedsToBeCalledWhenTheTimerIsFinished()
    4. {
    5.    // do some stuff
    6. }

    Is this possible and if so, how do I do it? I read some stuff about delegates but I have to admit that I don't really understood that...
     
  2. HiggyB

    HiggyB

    Unity Product Evangelist

    Joined:
    Dec 8, 2006
    Posts:
    6,183
    Look into coroutines, they'll be a big help here. For example, start here with StartCoroutine. :)
     
  3. Kentyman

    Kentyman

    Joined:
    Jul 14, 2009
    Posts:
    28
    I have it working now, here's what I did:

    I created a TimerFunctionsClass:

    Code (csharp):
    1.  
    2. using UnityEngine;
    3.  
    4.  
    5. public class TimerFunctionsClass: MonoBehaviour
    6. {
    7.     public delegate void OnTimerEvent();
    8.  
    9.     private OnTimerEvent CallBackFunction;          // the function that is called when the time is up
    10.     private float OriginalTimeInterval;                 // used for resetting
    11.     private float TimeLeft;                                 // used for counting down
    12.     private bool Active = false;
    13.    
    14.  
    15.     // setup the timer: how long should the timer wait and which function should it call when the event is triggered
    16.     public void SetTimer(float TimeInterval, OnTimerEvent NewCallBackFunction)
    17.     {  
    18.         TimeLeft = TimeInterval;
    19.         CallBackFunction = NewCallBackFunction;    
    20.     }
    21.    
    22.  
    23.     // actually start the timer:
    24.     public void StartTimer()
    25.     {      
    26.         Active = true;
    27.     }
    28.    
    29.  
    30.     // I'm not using this, but whatever:
    31.     public void StopTimer()
    32.     {
    33.         Active = false;
    34.     }
    35.    
    36.    
    37.     // ohwell
    38.     public void ResetTimer()
    39.     {
    40.         TimeLeft = OriginalTimeInterval;
    41.     }
    42.  
    43.    
    44. public void DestroyTimer()
    45.     {
    46.         Destroy(this);
    47.     }
    48.  
    49.  
    50.     // TimeLeft is decreased by Time.deltaTime every tick, if it hits 0 then the CallBackFunction is called
    51.     void Update()
    52.     {      
    53.         if (Active == true)
    54.         {  
    55.             TimeLeft -= Time.deltaTime;
    56.             if (TimeLeft <= 0)
    57.             {
    58.                 CallBackFunction();
    59.                 StopTimer();   
    60. DestroyTimer();
    61.            
    62.             }
    63.         }
    64.     }
    65. }
    And here is how I use the timer in my game code:

    Code (csharp):
    1.  
    2. void DoSomething()
    3.     {
    4.         Debug.Log("do something!");
    5.        
    6.     }
    7.  
    8. void Start()
    9. {
    10. TimerFunctionsClass MyTimer;
    11.                
    12.         gameObject.AddComponent("TimerFunctionsClass");
    13.         MyTimer = (TimerFunctionsClass)gameObject.GetComponent(typeof(TimerFunctionsClass));
    14.         MyTimer.SetTimer(10.0f, DoSomething);
    15.         MyTimer.StartTimer();
    16. }
    17.  
    it's probably not-so-good-code but it works for me :)
     
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    Thats actually bad code, not "not so good" I fear

    A simple coroutine and yield return WaitForSeconds(yourWaitTime); would do the same thing

    pause is not needed as setting the timescale to 0 will pause coroutines too and ending them is possible through StopCoroutine
     
  5. Kentyman

    Kentyman

    Joined:
    Jul 14, 2009
    Posts:
    28
    I tried using

    Code (csharp):
    1.  
    2. yield return WaitForSeconds(yourWaitTime);
    3.  
    but I could not get it to work, nomatter what I tried the error messages just kept becoming more and more exotic.

    Can you give me example code of a "good version" of this class? The code above works as intended but I suppose using WaitForSeconds would be more efficient.

    By the way, the delegate stuff is correct right?
     
  6. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    check out the script docs on StartCoroutine and WaitForSeconds

    they will give you an idea on coroutines.