Perform an action repeatedly after a random time for each repeat

I’d like to do what the subject says.

I have a function I’d like to call repeatedly (while loop), but with random time interval in between each iteration of the loop.

What would be a way to do this?

Here is what I’ve tried so far:

IEnumerator rotateAfterTime()
    {
        yield return new WaitForSeconds(0.2f + Random.Range(0, 10));
        rotate();
    }

void Update()
    {
        
        while (true)
        {
            rotateAfterTime();
        }
       
    }

This is a post better suited to the scripting forum. It has nothing to do with physics.

I’ll move it there.

1 Like

Time is a physical concept. But go ahead, thank you.

Do not write that while loop in your Update, updates run automatically every frame.

IEnumerator rotateAfterTime()
{
    while (true)
    {
        yield return new WaitForSeconds(0.2f + Random.Range(0, 10));
        rotate();
    }
}
void Start ()
{
    StartCoroutine(rotateAfterTime());
}

Try something like this.

2 Likes

To be clear then for the future; the physics forum is about Unity physics features, not concepts of (space) time in the same way that the forum isn’t about discussing Quantum mechanics or any other physical “concept”.

Your question is about control-flow and repeating a function call. Clearly nothing to do with Unity physics.

The great thing is that you now have an answer. :slight_smile:

2 Likes

Oh, okay. Thank you, and apologies.

This works, sort of. Canals (my game object) rotate, but they do so in groups. It appears they are synced. I have a top-down view of my 2D game so I can tell, plus debug text and IDs for each canal display grouped rotation times.

Could this be because they are prefabs, and I am using the GameObject brush from the official Unity Tilemap 2D extras package to paint them on the screen?

It’s not all-or-none, either, as you’d expect. It’s like, random groups of any number from 1 - max.

I’d assume from looking at @ 's code and yours, that it’s because of the Random.Range(0, 10). This only returns an int, so about 1/11th of the objects should sync up for the first rotation at least. Hard to tell without the full picture though.

1 Like

Here, this link to a vid capture on my Google drive should show the issue.
https://drive.google.com/file/d/1JAGuP24Gja13g3dnA_PLFH65xT2hkiN4/view?usp=sharing

Dumb question, why not use Invoke?

Also, Update is frame dependent, I would make my own counter that adds deltatime every frame until it exceeds the random value, then subtract the random value from the counter and pulls a new random value and start the process over.

That way the left over time will be added to the next cycle and it won’t matter what the framerate is.

1 Like

I haven’t fully processed what you said yet but it sounds really smart and like I should do it.

OK, no problem, let me go back over it.

so frame rates are not consistent. They change based on the hardware, and whatever else they are running.

if you are doing something that is a cycle of time you need to compensate for this fact.

as an example, let’s say you have a machine gun.

you are going to press down the primary fire, which will shoot a bullet.

Then you have a time to wait to shoot again.

If you simply use invoke, it will wait however long it takes to shoot again, BUT it does it by adding up all the time between frames until it’s greater than the value in the invoke statement, and just deletes all the time remaining.

This means the machine gun is firing slower than you want, and people with a lower FPS are shooting fewer bullets.

Instead what you should do is make your own float that adds up the time, and check it against the time between shots.

If the timer is greater than the time between shots, fire a shot and subtract the time between shots from the timer.

Now that remaining time is added to the next shot wait time.

So, if you do invoke and the time since your last shot is 1.5 seconds and the time between shots is 1 second, it will shoot and delete that 0.5 seconds.

Where as if you do your own timer it would subtract 1 from 1.5 and leave 0.5 seconds to add towards the next shot.

make sense?

Hi, just an update.

These canals are prefabs, so when I write a script for them, it applies to all of them. Why then random groups and not all of them? Strange. I thought I had it figured it out but still…

Will read your reply in a moment, thanks @Not_Sure .

BUT I will do it a different way rather than prefab game object brush in tilemap editor: I will do it scriptually, write code to keep track of the grid and the location of all the canals in a 2D array or other data type.

That should solve the problem, regardless of why it’s there.

Okay that makes sense, thanks. I’m wondering how this fits in contextually to my issue.

That is to say, I think I have a space issue, not a time issue, as far as my mental debugging is at this state.

Okay, so, now I want to store my canals in an appropriate data type that won’t elicit such behavior as above.

I’m going to add all the following info to a new forum post with a different name and link to it afterward. Be back shortly.