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.
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.
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.
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.
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.