Search Unity

How to Delay Without Using Coroutine

Discussion in 'Scripting' started by Alexander21, Nov 21, 2016.

  1. Alexander21

    Alexander21

    Joined:
    Dec 14, 2015
    Posts:
    302
    Hi all

    I am new bie to unity. In my project i am using animation. The enemy should come after certain seconds to the player after that the enemy should destroy with some seconds. i am using coroutine concept.


    public IEnumerator RobotAnimation()
    {

    yield return new WaitForSeconds(1.50f);
    if(test==false)
    {

    float step=speed* Time.deltaTime;
    Robot1.transform.position = Vector3.MoveTowards(Robot1.transform.position, Player.transform.position, step);
    yield return new WaitForSeconds(2.6f);
    Robot.CrossFade("Destroy");

    test=true;
    updatecheck=false;
    }
    }


    void Update()
    {
    if(updatecheck==true)
    {
    StartCoroutine(RobotAnimation());
    }
    }


    I have done that. I have no problem with that. But i have found the numerous times calling in update. i think it will cause issues because of numerous time calling in update.

    Is there any other way to delay. My Project the enemy should wait for 1.50 seconds after that it should walk after 2.6 seconds the enemy should destroy.

    how can i make the delay without using coroutine. or any other ideas welcome

    thanks in advance..
     
  2. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    838
    Hi Alexander! Just a reminder, use the code tags to post code.

    Code (csharp):
    1.  
    2. public IEnumerator RobotAnimation()
    3. {
    4.     yield return new WaitForSeconds(1.50f);
    5.  
    6.     if( test == false)
    7.     {
    8.         float step=speed* Time.deltaTime;
    9.         Robot1.transform.position = Vector3.MoveTowards(Robot1.transform.position, Player.transform.position, step);
    10.         yield return new WaitForSeconds(2.6f);
    11.         Robot.CrossFade("Destroy");
    12.  
    13.         test=true;
    14.         updatecheck=false;
    15.     }
    16. }
    17.  
    18.  
    19. void Update()
    20. {
    21.     if(updatecheck==true)
    22.     {
    23.         StartCoroutine(RobotAnimation());
    24.     }
    25. }
    26.  
    The `Update` method is being called every frame, it is clearly not what you want at the moment. Perhaps start your RobotAnimation routine in the Start method.

    Actually, if you read the manual on the Start method you can see it is possible to just make that a coroutine.

    Code (csharp):
    1.  
    2. IEnumerator Start()
    3. {
    4.         yield return new WaitForSeconds(1.5f);
    5.         float step=speed* Time.deltaTime;
    6.         Robot1.transform.position = Vector3.MoveTowards(Robot1.transform.position, Player.transform.position, step);
    7.         yield return new WaitForSeconds(2.6f);
    8.         Robot.CrossFade("Destroy");
    9. }
    10.  
     
    DroidifyDevs likes this.
  3. DroidifyDevs

    DroidifyDevs

    Joined:
    Jun 24, 2015
    Posts:
    1,724
    Coroutines are really easy. To start one (call this ONCE, NOT in Update function) use:

    Code (CSharp):
    1. StartCoroutine(YourName());
    And then use:

    Code (CSharp):
    1. IEnumerator YourName()
    2.     {
    3.         //you can replace 3 with the amount of seconds to wait
    4.         //for a time like 1.2 seconds, use 1.2f (to show it's a float)
    5.         yield return new WaitForSeconds(3);
    6.         Debug.Log("Finished waiting!");
    7.     }
     
    gnapan2003 and Georg-Axelsson like this.
  4. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    Don't worry about the Update function being called very often. Many function calls does not necessarily mean a performance issue, if that is your concern (though you might want to keep on eye on your Profiler).

    If you don't want to use coroutines, you would need to keep track of time using your own variables and accumulating the elapsing time using Time.deltaTime in the Update function.

    Alternatively, with animations, you could make use of Animation Events, which allows you to manually place events on your animation timeline.Then, when the animation is played and the event is reached, the corresponding function will be called on your MonoBehaviour. Beware that animation events are appropriate for cosmetic usage, such as synchronizing footstep sounds with the animation; it's not reliable to rely on this system for game logics.

    Also, if you want to handle more complex logic later on, you should look up for a programming techniques such as Finite State Machine or Behaviour Tree.
     
  5. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    Just a thought. When using code like this you'll want to be absolutely sure it's only run once when needed, so:
    Code (CSharp):
    1. void Update()
    2. {
    3.     //if(updatecheck==true)
    4.     if (updatecheck)  // Shorter way to say the same
    5.     {
    6.         updatecheck = false;  // < Toggle it here
    7.         StartCoroutine(RobotAnimation());
    8.     }
    9. }
     
    Bunny83 likes this.
  6. JacobGames

    JacobGames

    Joined:
    Dec 2, 2015
    Posts:
    12
    Hi Alexander

    waiting for several delays using coroutines is really tedious to implement with coroutines. That's because we created a simple asset (SuperInvoke) to implement delays and sequences in on line of code, to save time and make things easier.

    With Super Invoke your code would be:

    Code (CSharp):
    1.  
    2. sequence.AddDelay(1.5f)
    3.         .AddMethod(MoveRobotTowardPlayer)
    4.         .AddDelay(2.6f)
    5.         .AddMethod(DestroyRobot)
    6.         .Run();

    Check out this video for more details
     
  7. gnapan2003

    gnapan2003

    Joined:
    Mar 18, 2021
    Posts:
    1

    Thankyou very much brother i used Ienumeraturs as waiter function using bool value

    like function that takes time and bool which it makes true after waiting time