Is there no workaround for this? For example I have an ability that spawns 3 lightning strikes. It doesn’t do its damage until the lightning actually strikes. So I need to delay doing the damage sphere trace, etc… for a short period. However this doesn’t work because the event that spawns the lightning strikes will either ignore the delay or reset the timer.
The only solution I could find was to use a Niagara effect event and bind to it, but that’s incredibly unreliable as my particle effects can be culled and I need damage to reliably happen at a specific time.
if this is to only happen on a set interval, and there shall only be one per actor:
this could probably be fixed with a control boolean LigntningTicking (default to false)
when the trigger is invoked check against LightningTicking;
out the True do nothing
out the False: Set LightningTicking=True then fire off your delay and do your stuff, then after all of it Set LightningTicking=False
this way if there are multiple ways the Trigger can be Invoked it will only be counting once.
the default behavior is that for events if a timer is invoked, each time it is invoked is deemed unique and can be continued independently; so, if you call the Trigger 20 times, and each of them invoke a timer/delay then the resulting effect will happen 20 times after the delay value.
if you want it to happen no more then a certain number of times then you can swap the boolean to an integer, and replace the =True to a ++ and the =Fasle to a --
This happens multiple times not just once. So for example 5 lightning strikes. This is done from a loop. So Loop > Call Attack Event > Attack Event Spawns Particle > Delay > Do Damage is basically the barebones process here. I’ve tried both Delay and Set Timer by Event/Function. Both only ever execute once.
only 1 Delay can be active per node, and calling a Delay inside a loop will treat everything after the delay as non-existent until the delay finishes.
a Timer is like a Delay where only 1 can be active per Handle(the instance of the SetTimerByX() node), but gives additional controls in some ways (they do have a looping, but you need to have some way to stop it unless you want it active permanently)
(you can put the “Do Stuff” Section either before or after the increment)
I have this setup on an overlap collider for testing.
the important parts about using a naked loop is that you ensure your exit condition is reachable, and that anything happening inside it doesn’t impede performance.
If you wanted to do this with a Timer instead you would set it to Looping=True and then after the number of iterations has happened call ClearTimerByHandle() you would still need to manually keep track of the iterations.
Neither of the proposed solutions will work. These lightning strikes can happen all at once or may be over a period of time. So the delay needs to be unique per strike. For example Attack, 2 seconds later, Attack, 1 second later, Attack… it’s not consistent so they cannot share a timer or delay.
I guess my only option is to go back to use Niagara events unfortunately and binding to its delegate.
you can feed a variable as a value into the delay, maybe hold the value in a list/Array, and then get the value from the Array using the iterator as the index of the Array
DelayArray = [0,2,1,2,1]
then this array if exposed could be modified per instance (or at least in the Blueprint), then you can use the DelayArray.Length as the bound on the loop.
That seams far more complicated than just using Niagara events and will have to turn culling off for these type of attacks. Was just hoping to have better control over this using timers, but since it won’t create a new timer per-call to an event it’s a no-go.
I would rather not deal with the performance loss of spawning in and destroying a bunch of extra actors. Non-culled Niagara effects and using Niagara events will be better performance.
if that works for ya but like i said its no different than say spawning bullets which is very common, and you can use an actor pool to save some spawn/destroy performance