When you use the “Delay” loop you are setting a new delay by finding the manager and allocating and deallocating memory every time you loop.
“Set Timer by Event” gets set once and then lives on triggering the delegate function until it is stopped or destroyed.
Also the “Set Timer by Event” is guaranteed to call the function exactly the right amount of times even if the frame time goes above the loop duration.
So if the frame time goes above 0.5 then the “Set Timer” would call the function as many times as it takes to catch up on the next loop while the “Delay” would not.
if you do not care about the function happening outside of physics or rendering step then “Set Timer by Event” is the most consistent
if you want physics and Rendering to happen in between these actions then use a constrained DeltaTime on Tick()
Tick() did nothing wrong, people putting every actor in the same TickGroup or putting a bunch of stuff in Tick() causes performance issues far more then sensibly using a Event that already exists in the game loop call stack.