Not a Bug

Using wait in a for loop

odyssey96 3 years ago updated by Lazlo Bonin (Lead Developer) 3 years ago 4

Consider this scenario - I have 3 buttons below a game object called Main Menu


The flow reaches the for each loop and sets the bool parameter to true correctly on all 3 buttons.  Notice the 1 second wait in the flow.  Then I can confirm from the Debug Log message that the last step of setting the bool parameter to false, the item this unit is passed is the last item in the child collection (the 3rd button).  It's almost as if the enumerator in the for each loop is progressing when the flow hits the wait unit.

If I bypass the wait unit, the Debug Log shows that the correct item is passed to the last  Animator.SetBool unit to set the value to false (i.e. the 1st button, then the 2nd button, then the 3rd).  

In between the For each loop and 1st animator.setbool unit I added a cache unit to cache the result, and had all the value connections for the item connect to the cache unit, but the 1st animator throws and invalid operation exception (missing animator) so this did not prove successful alternative for testing (and may even raise another issue?)

Is this a bug?

Bolt Version:
Unity Version:
Scripting Backend:
.NET Version (API Compatibility Level):

This is not a bug. A for loop or for each loop happens on a single frame, all of its loop throughs do. A wait unit happens over multiple frames and is Async. So every time a wait unit is fired, a New wait occurs as a Coroutine, but it cannot prevent the loop from iterating, so your still looping, but the delay happens multiple times in a single frame. So you'll fire a wait, and it'll wait, but in the same frame it'll move on to the second iteration, but also throw a new wait. By the end, after time, all those waits will finish simultaneously.

There are ways around it, but I'll take being clever. You'd probably need to make your own super unit, somehow create your own multiple frames loop. There is my units Flow Control in the Macros section, which provides a more advanced version of the wait loops, which you can break, do stuff while looping, and block incoming iterations if it's still running an instance. It's a start, but you'll still need to figure out iterating over a set of objects with it if you really want to wait during a loop.

Thanks for the reply.

I really need a coroutune for this I guess, what I'd really want is a method of creating coroutines on the fly in graphs with units.  I see you have made the Flow Control extensions, may I ask did you download the source and figure out the API for Bolt to allow you to specify multiple connection points for your units on the inbound/outbound (like Do Once having Do once having 2 inbound connection ports and 2 outbound connection ports) or is there some Bolt API docs somehwere?  I will want to build a unit which progresses though the remaining connections as a coroutine effectively. 

Yup, I used the API to do all you mentioned. You can even put input and output ports in a for loop to allow users of the unit to add and subtract ports like a sequence. I used the CoroutineRunner.instance to create a new instance, then you can use start and stop Coroutine like normal with your own Coroutine functions. You invoke a specific port with flowInstance.Invoke(portVariable). If you needed some extra assistance, private message me on Discord, and I'll help you when i can. Same name as this one. If you goto Builds on the site, you can download the source. Just look up something that has functionality your looking for.

You could pretty easily do what you need, I originally was going to do that, but needed to start putting some effort into my games, instead of tools for now. 

Not a Bug

I will close this as not a bug, but I am taking into consideration what you're trying to accomplish, and I'll try to make it simpler in future versions.