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