For Loop with timer between iterations - Visual Scripting / Bolt

Hello everyone.

I am trying to add a short timer between iterations of a For loop in Visual Scripting / Bolt.

I’ve just been experimenting and have tried using things like Wait, Wait Until, Timer, Once, and a few others. I thought it would be pretty straight forward, but I can’t seem to get it to fire a movement a second time. The debug shows the loop does iterate through each number (Shows: 1,2,3,4, etc, correctly) but the object itself will only move the first time / first loop. The object should essentially move a set distance, like 10 units, per hop. 1 hop is 10 units, 3 hops is 3 units, but over time, and not all combined into one invisible movement at once (I’d like to add that the object had no issues moving the total max distance from A to B prior to trying to add this ‘pause between hops’ logic)

I expected to be able to say ‘do a loop this many times’, and each exit would be one instance of that loop. As such, simply add a short timer between each of those instances so the movement isn’t one quick action, but broken into steps.

Can someone please help point me in the right direction, please? It does trigger the timer and pause it the first run - but it never comes back and runs the timer a second time.

This is one example. Start loop, with X iterations. Debug properly shows results, but the timer itself here only fires once.

7382252--900806--upload_2021-8-2_7-56-45.png

1 Like

I want to add that I also set it up as a coroutine like this, as I’ve seen suggested online. I’ve searched a number of places and tried a number of things and there doesn’t seem to be a lot of pre-existing ‘support’ for bolt (i guess because of its newness) compared to like C#. And I do see how to do it in C#, but I’d like to keep it all in VS/bolt if possible.

7382276--900899--upload_2021-8-2_10-41-44.png

I’ve written a little visual script that does the job.

The Update Graph won’t work until “Ready to Move” is true. It only gets set to True by the Custom Event coroutine that waits for a specified time. I’ve given the Custom Event an argument so you can specify the wait time.

Fit your own loop and movement into the mix but this framework should be OK and is quite efficient (within the current performance limitations of VS variables)

Happy to answer questions…

1 Like

Thank you for the reply Beechside, it was really helpful to see the different approach.

I’ve been working on this since your post, am still not having any luck.

The change I implemented, was basically putting in your logic, with my movement stuff where your ‘Vector 3 Create’ is. So I figured it would do all the timer stuff, then hit the for loop, and trigger the wait.

The activity I’ve experienced so far ranges from the object moving on startup (versus being triggered by the button itself), where it is moving in a direction but there is no set direction. The for loop, and while loop, were ignoring the comparison values (stop at 3 loops), and just keep looping - but with the timer in place!! Which I am happy about.

Alternatively - I’ve managed to create some kind of infinite loop and completely lock up and crash out Unity. So yay for progress. :slight_smile:

I have had some partial success, in a ‘move 5’ scenario, it will do the 1, then the 2. Skip 3 and go right to 4, and then skip 5. Weird stuff like that for some reason, but I am still toying around with it. I hope to post a correct result toon.

OK, rather than give you a solution, some hints…

  • Create a manual loop, rather than a For Loop
  • Increment the loop index yourself but only when a time period has expired
  • Only move if “Ready to move” and “Less than loop max”
  • Exit routines should always test for “Less than” or “Greater than or equal”, not “Equal”, just in case you overshoot the exit criterion

Hope that helps!

Amazing timing! I was just writing another response myself, thanks for the additional feedback Beechside. I’m looking at that now and will incorporate the suggestions.

I had implemented my ‘best one yet’, but still not quite there yet. This uses the individual hops along the way (the delay I wanted), and stops at the desired location, which is awesome.

It seems to be skipping the ‘even’ hops for some reason. Am still trying to sort that out. Where, if I say ‘move 5 units’, it will move to hop #1, then jump to where the 3rd hop would be, then jump again to where the 5th hop would be. This occurs the same with all odd counts. And even counts too, it just goes 1-2-4, instead of 1-3-5.

I’m not sure why the ‘start’ and setting wait is needed - could the ‘Ready to Move’ bool just be true by default? If we are always setting it to false once we initiate a movement anyway, can the ‘Ready to Move’ be set on the movement call, and be set back to null at the end of the action?

I can see how both work and why both, and am wondering if it is a preference or if it is better this way for technical reasons? (Still trying to learn :slight_smile: )

Why is Start used? Only to create a delay before the first move. If you don’t want an initial delay then don’t use it but see my second point…

Can Ready to Move be true by default? Yes but there is a matter of coding style here. Do you want to see all the entry conditions by looking at the graphs alone? If so, explicitly initialise your variables in a Start or Awake unit. If you are happy to hunt through your variables’ properties (graph, object, scene and application) to find the initial values, then use the variable default. Old-timers like me prefer to see initialisation put into a more obvious place. Use Start or Awake and create a superunit/subgraph to do explicit initialisation, thereby keeping things tidy.

I don’t like to see your Custom event joining up with another flow into the branch on the RHS. Events should not join the main logic. They run and they die and are completely independent of the main On Update flow. I think that’s causing you to miss out the evens - I can’t see the RHS of your network…

I agree with your comment about the Custom Event joining with the flow being wonky. It was really the only way I got it to even partially work. I am looking to correct that as I know it isn’t proper (was the ‘best one yet’ joke I made).

This I think is the key to my lack of knowledge and understanding about the ‘basics’ here. Notice the click event. I want to set a distance value with one action, and initiate the movement itself (using ‘Click’) with a second action. The timer itself would only really be needed (I think) when the ‘Click’ action is called.

Assuming this is remotely the best approach to getting this done - how do I get ‘Click’ and ‘Wait’ to intermingle? I have the ‘Custom Event Trigger (Wait)’ at the end of the movement cycle. Which itself would trigger the Wait Custom Event / ReadyToMove bool. But… how do I get back to the ‘Click’ event, from the ‘Wait’ event?

I think that is exactly what I can’t figure out. I can’t replace ‘Wait’ with ‘Click’ either, because that is then the infinite loop scenario, where it gets called each update cycle. I’m having a problem understanding the proper action flow or logic of it.

Click ‘X’ to move a set amount, but use the step/timer/wait between each of the sub-movements (‘Y’) within that max amount. Like a chess piece, that stops at each square along its dynamic path across the board. Versus just appearing at the final destination.

Still not exactly sure what it is you are trying to do. There are many ways to introduce a delay. If you want another - one that doesn’t use co-routines - here’s an alternative. It starts a timer at zero and, every frame, adds up how much time has elapsed. After 1 second the flow passes through the If unit. You could try putting your logic to the right of that.

Good luck!

Hi Beechside, others,

I wanted to follow up and say thank you for your help. This was a useful and successful solution, I had the desired results before everything went crazy with my Unity/Bolt/VisualScripting versions (I have another post going about an issue I was having with Bolt ignoring the Flow Macro names). I basically haven’t touched the code in a few days because of the crazy other issue I was having - but I wanted to follow up and say it worked finally, and thanks.

I was able to remove the For Loop, and just use the traditional ‘Wait’ and Custom Event call, with an index Branch check if it hits it limit. It worked perfect and am rebuilding everything now using the proper software versions / compatibility.

You rock. Thanks.