How to create recoil that's not instant?

Alright I figured it out, the secret was Timers.

All props to this guy, made a pretty bad *** flying aircraft.
https://answers.unrealengine.com/questions/63894/barrel-roll-mechanic.html?sort=oldest

Your going to need to add a Tick method, a timer to the world, a stop recoiling method, and a boolean.

I also added a random recoil to the left and right to give it a little more randomness (but it moves both left and right within one shot, so to make it perfect you would have to add a boolean and another random generator to chose a direction and then apply the random number in that direction, not something that is hard to do, but I didn’t want to over complicate what was asked).

Now of course these are all linear, if you wanted to be crazy you could maybe find a way to manipulate FinalRecoil on each tick to make it more curvy, to simulate something more realistic. Unfortunately the linear movement look very robotic on a crouch feature and I’ll have to implement some sort of curve.



**void AShooterCharacter::Tick(float DeltaSeconds)
{
	if (isRecoiling)
	{
		FinalRecoilPitch = Recoil * FMath::FRandRange(-1.0f, -1.25f);
		//FinalRecoilYaw = Recoil * FMath::FRandRange(5.0f, -5.0f);
		AddControllerPitchInput(FinalRecoilPitch);
		//AddControllerYawInput(FinalRecoilYaw);
	}

	// call the parent class Tick implementation
	Super::Tick(DeltaSeconds);
}**


*void AShooterCharacter::OnFire()
{
	// try and fire a projectile
	if (ProjectileClass != NULL)
	{
		const FRotator SpawnRotation = GetControlRotation();
		// MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
		const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

		UWorld* const World = GetWorld();
		if (World != NULL)
		{
			// spawn the projectile at the muzzle
			World->SpawnActor<AShooterProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);
		}
	}

	// try and play the sound if specified
	if (FireSound != NULL)
	{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
	}

	// try and play a firing animation if specified
	if(FireAnimation != NULL)
	{
		// Get the animation object for the arms mesh
		UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
		if(AnimInstance != NULL)
		{
			AnimInstance->Montage_Play(FireAnimation, 1.f);
		}
	}*


	**GetWorldTimerManager().SetTimer(this, &AShooterCharacter::StopRecoil, .1f, true);
	isRecoiling = true;**
}

**void AShooterCharacter::StopRecoil()
{

	isRecoiling = false;
	GetWorldTimerManager().ClearTimer(this, &AShooterCharacter::StopRecoil);
}**




(The underlined is what needs to be added, the italicized is part of the default class)

I hope this helps