ForEachLoop crashes with InfiniteLoop

Hello,
I am doing a very simple loop where I check if I already processed a location.
I loop through the list of all processed location to find the current location and return true/false if the location has been found.

When testing my program on large scale the list of location starts to be quite large and UE crashes with an infinite loop error.

See the code :

I tried doing an array of array using structures and limite the array to 1000 elements but still the same result:

How can I loop trought large arrays without having the infiniteLoop error triggered ?

Thanks in advance

The most performant way would be to push this to a separate thread but that requires c++.
Any type of larger loop operation is usually better in c++ than in blueprints.

3 Likes

Use For loop with break instead.

I am guessing now, but i think that infinite loop of doom is not this loop.
When you return you probably execute same loop again. That return node causes next iteration of for loop without ending previous one.

This code is similar to recursive loops.

1 Like

I am pretty sure this is the actual loop that UE consider “infinite loop”.
If I bypass the function, I don’t have the error.
If I run the code with smaller numbers of location, I don’t have the error.

This is really due to scaling once the list starts to be bigger. Even if it is not an infinite loop, it is still triggering the UE infinite loop detection.

Hello @Wyziwig try going to your project settings and increasing maximum loop iteration count to a bigger number

Whaat i mean that for loop may be not actual loop is this:

  • you call for loop
  • condition is true, you call RETURN node
  • first loop never finished
  • you enter second loop
  • repeat.

So your code actually never finishes any of those loops

use for loop with break

It’s a function, it short circuits the moment it exits :slight_smile: ( it doesn’t run anything else at that point ).

1 Like


This works ok no problem even with a 1000 generated points being called every second :slight_smile:
Nawrot was right.

Print node can be omitted, it’s for debug purposes.

Yeah I just tried the same kind of loop :

It works better but still gets an infinite loop error if we keep scaling ^^

To me it makes no sens that a loop with break is better because as ClockworkOcean mentionned when you exit the function the loops are stopped anyway.

Ok this is better but still the error of the infinite loop arrives on larger scale.


For larger loops you can try increasing the project loop limit but performance will be diminished.
Again, I’d push you to look into c++ for loops. It’s basic programming and works better than bp.

If you are testing against actor locations then perhaps a sphere trace with a radius would be more performant. No need to get all locations in that case.

a good technique is to process across several frames. for that you need to do it in chunks.

you would need to keep the values in variables for that duration and each frame only test X amount of items.

there’s not a huge difference in performance, really. since it will take the time it takes. (unless you under-use a frame time).

this kinda behaves as if you run it on a bg thread with a lower tick interval. even if this fits in one frame, i wouldn’t run such test every single frame.

if you really need to perform this whole check every single frame, then i think you might want to rethink what you need.

the way i’d do it is this.

  • have flag ChunkSize = XX . set the default value to something you have tweaked. try to maximize the frame time but leave some slack. not all pcs are equally fast and your project will grow in complexity

  • Have delegate CheckDone with 2 params (Found, and Location)

  • bind to CheckDone to some function eg CheckDoneCB

call StartCheck with your values.

  • if working then return (safeguard)
  • store values into variables
  • set “working” flag to true
  • set flag currentIndex = 0
  • set timer for next tick to “Check”

In Check:

  • iterate using indexes. from CurrentIndex to Math.Min(CurrentIndex+ChunkSize, Array.Num) -1 (bp loops indexes are inclusive)
  • if found:
    ** Set working to False
    ** broadcast CheckDone(True, Location)
    ** return
  • if reached end
    ** set CurrentIndex += ChunkSize
    ** if currentIndex >= Array.Num :
    *** set working to False
    *** broadcast CheckDone(False, Zero)
    *** return
    ** else: SetTimerForNexTick(Check)

in CheckDoneCB:

  • if Found: do your stuff. else Ignore or do your other stuff.

i just did it from memory, so it could be broken. but that’s the general idea.

otherwise you could use some form of hashgrid.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.