Auto-Fire Projectile

changing default FPS template weapon to shoot full auto

As of UE5 use of the PlayerInputComponent for registering input has been replaced by the EnhancedInputComponent.

Projectile

Luckily the First Person template comes with a projectile, however it's currently semi-auto and we want full-auto glory.

Full-Auto

The idea here will be when the user presses the fire input we start a timer which executes Fire() every X seconds on a timer, and stops once the fire input is released.

Input Binding

Add two new InputActions and bind them to input events and callbacks

.h

// TP_WeaponComponent.h

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
class UInputAction* StartFireAction;

UPROPERTY(EditAnywhere, BlueprintReadOnly, Category=Input, meta=(AllowPrivateAccess = "true"))
class UInputAction* EndFireAction;

.cpp

// TP_WeaponComponent.cpp

void UTP_WeaponComponent::AttachWeapon(AGlooCannonCharacter* TargetCharacter)
{
    //...
    // old
    EnhancedInputComponent->BindAction(FireAction, ETriggerEvent::Triggered, this, &UTP_WeaponComponent::Fire);

    // new
    EnhancedInputComponent->BindAction(StartFireAction, ETriggerEvent::Triggered, this, &UTP_WeaponComponent::StartFire);
    EnhancedInputComponent->BindAction(EndFireAction, ETriggerEvent::Triggered, this, &UTP_WeaponComponent::EndFire);
    //...
}

Notice the difference from UE4 where we would have used a single action with two different input events (IE_Pressed and IE_Released) versus UE5 where now each action uses the same Triggered event (for more details UE docs here)

Implement Callback Functions

.h

// TP_WeaponComponent.h

UFUNCTION(BlueprintCallable, Category="Weapon")
void StartFire();

UFUNCTION(BlueprintCallable, Category="Weapon")
void EndFire();

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
float BulletsPerMinute = 450;

float TimeBetweenShots;
FTimerHandle TimerHandle_BetweenShots;

.cpp

// TP_WeaponComponent.h

UTP_WeaponComponent::UTP_WeaponComponent()
{
	//...
	TimeBetweenShots = 60.f / BulletsPerMinute;
}

void UTP_WeaponComponent::StartFire()
{
	const float intialDelay = FMath::Max(TimeBetweenShots - GetWorld()->TimeSeconds, 0.f);

	if (UWorld* myWorld = GetWorld())
	{
		myWorld->GetTimerManager().SetTimer(TimerHandle_BetweenShots, this, &UTP_WeaponComponent::Fire, TimeBetweenShots, true, intialDelay);
	}
}

void UTP_WeaponComponent::EndFire()
{
	if (UWorld* myWorld = GetWorld())
	{
		myWorld->GetTimerManager().ClearTimer(TimerHandle_BetweenShots);
	}
}

InputAction setup and mapping

Like mentioned since UE5 uses the new EnhancedInputComponent there is a bit more we need to do to hookup the actual input.

Create two new Input Action data assets

InputAction data assets

one for "Pressed" and one for "Released

creating our own Pressed and Release actions

Next add them to the Input Mapping Context

only adding mouse support for simplicity but you can add whatever other input you desire

IMC_Weapons: Input Mapping Context add two new Input Actions

Lastly we need to assign the new Input Actions to the weapon blueprint

BP_Pickup_Rifle::TP_Weapon
default weapon now shoots fully auto

Last updated