Download

I've made burst fire function, but it don't work how I want.

Burst is set to 3. It returns 3 “Pew”, but shoots only 2 projectiles. It is because Im calling same Timer.

How can I make it working properly?


PullTrigger();
for (int i = 1; i < Burst; i++)
{
GetWorld()->GetTimerManager().SetTimer(TimerHandle, this, &AGun::PullTrigger, ShootDelay, false);
UE_LOG(LogTemp, Warning, TEXT("Pew"));
}

Good day to you.

By using a TimerHandle you overwrite the time for the timer that belongs to the handle. So the first call will create the timer, the 2nd and 3rd will just “renew” the time.
You get two projectiles cause of the PullTrigger(); manual call.

I know. I was asking how to change it.

By not using the same timer handle for all 3 timers?

But I want to make it easily changable.

You need to be less rigid in how you are approaching the problem. Right now you’re thinking “I have this function that fires, so if I want burst fire I’ll just fire it three times” rather than “I have these pieces how do I use it to make something burst-y”. As Rumble said, you need to add NEW logic and not re-use the same thing.

You could take those pieces and do something like this:



FTimerHandle BurstHandle; // New handle for Burst functionality.

int BurstCount; // Expose this to BP or whatever.

void BurstFire()
{

    PullTrigger();
    BurstFire = FMath::Max(BurstFire - 1, 0); // Clamp us to never dropping below 0.
    if (BurstFire > 0) // Do we still need to fire more?
    {
      GetWorld()->GetTimerManager().SetTimer(BurstHandle, this, &AGun::BurstFire, BurstDelay, false);            
    }
}


tl;dr - Less copy and paste coding, more understanding what your code is doing so you can better manipulate it.

Thanks for advice and code.

I would suggest not using a timer at all for this. A more reliable and controllable way of doing this would be to trigger a burst via player input and then update the logic in the tick.

For instance, let’s say that you want your burst fire to contain 3 shots with a fire rate of 1 per second (super long, I know, but simpler numbers for this discussion). The player presses the fire button and your weapon system picks that up. You set one or more variables (one of which should be either the current time or a float to use as a simple timer) to record that a burst fire has been requested (you could also immediately fire the first shot here if you want). Then in the tick function, you update and check your timer and fire the next shot after 1 second has passed. When you’ve fired the last shot in the burst, you reset your variables.

Doing it this way is easier to follow and debug and also gives you more control on how everything functions. For example, if you end up in a case where you need to fire two bullets in the same frame, you might decide that you only want to play the VFX and SFX for one of those bullets for aesthetic or performance reasons. Doing it this way also gives you better control over what happens if the player presses the fire button again in the middle of the burst. Presumably, you want to ignore any fire inputs in the middle of a burst. With this system, you’ll always know if a burst is active and you can react accordingly.

Can I make this without using Tick?

yes you can.