Wait for second without StartCouroutine?

What is the other way to get wait for second without using yield WaitForSecond?

I’ve seen someone using something like this:

float time = 10.0f;

time -= Time.deltaTime;

Yeah that’s what I do. Classic state stuff. Doubt there’s any performance difference to speak of.

Doing something 5 seconds after the player presses space:

private float pressedSpaceTime;
private bool hasPressedSpace;

void Update() {
    if(Input.GetKeyDown(KeyCode.Space)) {
        hasPressedSpace = true;
        pressedSpaceTime = Time.time;
    }

    if(hasPressedSpace && Time.time - pressedSpaceTime > 5f) {
        //do something
        hasPressedSpace = false;
    }
}

Or you could do it with subtraction:

private float spaceTimer;
private bool hasPressedSpace;

void Update() {
    if(Input.GetKeyDown(KeyCode.Space)) {
        hasPressedSpace = true;
        spaceTimer = 5f;
    }

    if(hasPressedSpace) {
        spaceTimer -= Time.deltaTime;

        if(spaceTime <= 0f) {
            //do something
            hasPressedSpace = false;
        }
    }
}

Both of these designs clutter your code with extra fields, and your Update code suddenly contains a bunch of garbage that’s run only occasionally. A coroutine is so_much_better:

void Update() {
    if(Input.GetKeyDown(KeyCode.Space)) {
        StartCorotuine(WaitAndDoSomething());
    }
}

IEnumerator WaitAndDoSomething() {
    yield return new WaitForSeconds(5f);
    // do something
}

If you need to abort the waiting, the coroutine becomes a bit harder to use, but I still think the coroutine code just reads better.

(inb4 @ericbegue tries to sell his mediocre behaviour tree framework since somebody mentioned the word “coroutine” in a thread)

5 Likes

I hope not, since asset spam from original author is not welcome. It should be reserved for the asset thread, or mentioned by other users in passing.

I need to abort the waiting that why I made this thread. Anyway, I’m fine with your second method.

Here’s a little class I use for simple timing things like this. This is from memory so it might need a little tweaking but this is the gist of it.

public class Delay
{
    public float WaitTime;
    private float completionTime;

    public Delay(float waitTime)
    {
        WaitTime = waitTime;
        Reset();
    }

    public void Reset()
    {
        completionTime = Time.time + WaitTime;
    }

    public bool IsReady { get { return Time.time >= completionTime; } }
}

Use it like this…

Delay delay = new Delay(5.0f);
...

if (delay.IsReady)
{
    // do stuff when the timer expires

    // re-schedule for 5 more seconds in the future
    delay.Reset();
}

Cleans up the code quite a bit so you don’t need to have the variables and the time increment/decrement stuff, and you don’t need to purchase any large asset libraries. :wink:

But yeah, Coroutines are ideal for this sort of thing as well.

2 Likes

If you hold onto the coroutine returned by StartCoroutine then aborting it should be as simple as calling StopCoroutine. Unless I’m missing something?

4 Likes

So I wasn’t the only one who noticed this.
This has happened numerous times in forums regarding this asset.

Ok he’s had a warning and I’ll delete his stuff. It’s simple.

1 Like

This. Here’s a modified version of the example from the Unity documentation on the page for StopCoroutine.

private IEnumerator coroutine;

void Start() {
    coroutine = WaitAndDoSomething();
}

void Update() {
    if (Input.GetKeyDown(KeyCode.Space)) {
        StartCoroutine(coroutine);
    }

    if (Input.GetKeyDown(KeyCode.Escape)) {
        StopCoroutine(coroutine);
    }
}

IEnumerator WaitAndDoSomething() {
    yield return new WaitForSeconds(5f);
    // do something
}
2 Likes

You can also get the best of both worlds by putting a custom timer inside a coroutine.

3 Likes

this, you can do a per frame timer by yielding on null in a while loop, just like you would in a Update, but also you can scope everything to the coroutine its self, thus not cluttering up your object with extra fields.

private IEnumerator TimerTest(float duration) {
    var timer = 0f;
    while (timer < duration) {
        yield return null;
        timer += Time.deltaTime;
        // Do Stuff here over duration here
    }
    //  Do stuff after duration here
}
3 Likes

You could also use the Invoke method to run a function after some delay.

//Wait 2 seconds, then execute DoSomething()
Invoke (“DoSomething”, 2);

Cheers

2 Likes

main downside to invoke, is that it requires you pass in the method name as a string, instead of taking it as a delegate which is a lot more flexible.

2 Likes

Thanks to all! I got it working now. So many different method I could use in the future script.

@GTHell
So many methods indeed. If you happen to use BT in the future, don’t mention it or you’ll get censored.

There is nothing wrong with mentioning an asset while assisting someone. From what I’ve gathered reading the posts in this thread though you were spamming an advertisement in many of the threads that made mention of coroutines regardless of whether it was relevant or not.

That’s what I thought as well.

Being classified as spammer is rough. I don’t think I am trying to sell snake oils or any body part enlargement pills by using an army of spam-bots.

About the relevancy of my answers. Coroutine, FSM and BT in game development are used to solve the same problem: defining execution flow that spans several frames. These topics are part of my area of interest, so it is very likely to found me on the threads related to these topics. I’m a Behaviour Tree enthusiast and I’ve made an asset using this technique, is that so unexpected that I’m promoting it?

However, my first post on this thread was a reaction to:

@Baste , in case you didn’t read my answer because it has been “moderated”, you are welcome of this thread to make any suggestion to decrease the mediocrity of this asset.

I guess my issue is about:
(from the the Unity Developer Network Rules)

I am not a spammer and don’t copy/paste posts and I do not post ads.

Does posting a link or referring to my asset is considered as spamming?

Perhaps some tips from someone who has had success pushing products through the forums?

PandaBehaviour is a decent asset. You’ve just managed to get a reputation for pushing the asset in every thread, regardless of weather it actually solves the OPs problem or not. You’ve got to learn where it is appropriate, and where it is just annoying.

Here are some places where PandaBehavior makes sense

  • As a replacement for a FSM
  • Where someone want to simplify complex state behaviour
  • Where someone is interested in modern AI techniques
  • As a way to simplify majorly complex coroutines

Here are some places where PandaBahaviour does not make sense.

  • As a replacement for a coroutine
  • For a simple timer
  • As a response to any question from a beginner

You also want to be sure to actually answer the question. Normally the simplest solution is the best. So be sure to at least share the simple direct solution.

And finally you need to be sure to spend plenty of time in the community not talking about your product. Help out on stuff that doesn’t involve your product at all.

Anyway, hope it helps. It takes a while to change your reputation around here. But it can be done.

And sorry @GTHell for further derailing your thread.

5 Likes

@Kiwasi It’s ok since my case is solved.

1 Like