super-duper-spoon/Source/Shooter/ShooterAnimInstance.cpp

231 lines
6.1 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "ShooterAnimInstance.h"
#include "ShooterCharacter.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "Kismet/KismetMathLibrary.h"
#include "Weapon.h"
#include "WeaponType.h"
UShooterAnimInstance::UShooterAnimInstance() :
Speed(0.f),
bIsInAir(false),
bIsAccelerating(false),
MovementOffsetYaw(0.f),
LastMovementOffsetYaw(0.f),
bAiming(false),
TIPCharacterYaw(0.f),
TIPCharacterYawLastFrame(0.f),
RootYawOffset(0.f),
RotationCurve(0.f),
RotationCurveLastFrame(0.f),
Pitch(0.f),
bReloading(false),
OffsetState(EOffsetState::EOS_Hip),
CharacterRotation(FRotator(0)),
CharacterRotationLastFrame(FRotator(0)),
YawDelta(0.f),
RecoilWeight(1.f),
bTurningInPlace(false),
EquippedWeaponType(EWeaponType::EWT_MAX),
bShouldUseFABRIK(false)
{
}
void UShooterAnimInstance::UpdateAnimationProperties(float DeltaTime)
{
if (!ShooterCharacter)
ShooterCharacter = Cast<AShooterCharacter>(TryGetPawnOwner());
if (!ShooterCharacter) return;
// Get the lateral speed of the character from velocity
FVector Velocity{ ShooterCharacter->GetVelocity() };
Velocity.Z = 0;
Speed = Velocity.Size();
// Is the character in the air
bIsInAir = ShooterCharacter->GetCharacterMovement()->IsFalling();
// Is the character accelerating
bIsAccelerating = ShooterCharacter->GetCharacterMovement()->GetCurrentAcceleration().Size() > 0;
FRotator AimRotation = ShooterCharacter->GetBaseAimRotation();
FRotator MovementRotation = UKismetMathLibrary::MakeRotFromX(ShooterCharacter->GetVelocity());
MovementOffsetYaw = UKismetMathLibrary::NormalizedDeltaRotator(MovementRotation, AimRotation).Yaw;
// if (GEngine)
// {
// GEngine->AddOnScreenDebugMessage(0, -1, FColor::Red, FString::Printf(TEXT("MovementYaw: %f"), MovementYaw));
// GEngine->AddOnScreenDebugMessage(1, -1, FColor::Red, FString::Printf(TEXT("MovementInputYaw: %f"), MovementInputRotation.Yaw));
// GEngine->AddOnScreenDebugMessage(2, -1, FColor::Yellow, FString::Printf(TEXT("AimYaw: %f"), AimRotation.Yaw));
// GEngine->AddOnScreenDebugMessage(3, -1, FColor::Cyan, FString::Printf(TEXT("MovementOffsetYaw: %f"), MovementOffsetYaw));
// GEngine->AddOnScreenDebugMessage(4, -1, FColor::Cyan, FString::Printf(TEXT("HipRotationOffsetYaw: %f"), HipRotationOffsetYaw));
// }
if (ShooterCharacter->GetVelocity().Size() > 0)
{
LastMovementOffsetYaw = MovementOffsetYaw;
}
bAiming = ShooterCharacter->GetAiming();
bReloading = ShooterCharacter->GetCombatState() == ECombatState::ECS_Reloading;
bCrouching = ShooterCharacter->IsCrouching();
bEquipping = ShooterCharacter->GetCombatState() == ECombatState::ECS_Equipping;
bShouldUseFABRIK = ShooterCharacter->GetCombatState() == ECombatState::ECS_Unoccupied
|| ShooterCharacter->GetCombatState() == ECombatState::ECS_FireTimerInProgress;
if (bReloading)
{
OffsetState = EOffsetState::EOS_Reloading;
}
else if (bIsInAir)
{
OffsetState = EOffsetState::EOS_InAir;
}
else if (bAiming)
{
OffsetState = EOffsetState::EOS_Aiming;
}
else
{
OffsetState = EOffsetState::EOS_Hip;
}
// Check if ShooterCharacter has a valid EquippedWeapon
if (ShooterCharacter->GetEquippedWeapon())
{
EquippedWeaponType = ShooterCharacter->GetEquippedWeapon()->GetWeaponType();
}
TurnInPlace();
Lean(DeltaTime);
}
void UShooterAnimInstance::NativeInitializeAnimation()
{
Super::NativeInitializeAnimation();
ShooterCharacter = Cast<AShooterCharacter>(TryGetPawnOwner());
if (!ShooterCharacter) return;
TIPCharacterYaw = ShooterCharacter->GetActorRotation().Yaw;
TIPCharacterYawLastFrame = TIPCharacterYaw;
}
void UShooterAnimInstance::TurnInPlace()
{
if (!ShooterCharacter) return;
Pitch = ShooterCharacter->GetBaseAimRotation().Pitch;
if (Speed > 0 || bIsInAir)
{
// Don't want to turn in place; Character is moving
RootYawOffset = 0.f;
TIPCharacterYaw = ShooterCharacter->GetActorRotation().Yaw;
TIPCharacterYawLastFrame = TIPCharacterYaw;
RotationCurve = 0.f;
RotationCurveLastFrame = 0.f;
}
else
{
TIPCharacterYawLastFrame = TIPCharacterYaw;
TIPCharacterYaw = ShooterCharacter->GetActorRotation().Yaw;
const float TIPYawDelta { TIPCharacterYaw - TIPCharacterYawLastFrame };
// Root Yaw Offset, updated and clamped to [-180, 180]
RootYawOffset = UKismetMathLibrary::NormalizeAxis(RootYawOffset - TIPYawDelta);
// 1.0 if turning, 0.0 if not
const float Turning { GetCurveValue(TEXT("Turning")) };
if (Turning)
{
bTurningInPlace = true;
RotationCurveLastFrame = RotationCurve;
RotationCurve = GetCurveValue(TEXT("Rotation"));
const float DeltaRotation { RotationCurve = RotationCurveLastFrame };
// If RootYawOffset > 0, -> Turning Left, If RootYawOffset < 0, -> Turning Right
RootYawOffset > 0 ? RootYawOffset -= DeltaRotation : RootYawOffset += DeltaRotation;
const float ABSRootYawOffset { FMath::Abs(RootYawOffset) };
if (ABSRootYawOffset)
{
const float YawExcess { ABSRootYawOffset - 90.f };
RootYawOffset > 0 ? RootYawOffset -= YawExcess : RootYawOffset += YawExcess;
}
}
else
{
bTurningInPlace = false;
}
}
// Set the recoil weight
if (bTurningInPlace)
{
if (bReloading || bEquipping)
{
RecoilWeight = 1.f;
}
else
{
RecoilWeight = 0.f;
}
}
else
{
if (bCrouching)
{
if (bReloading || bEquipping)
{
RecoilWeight = 1.f;
}
else
{
RecoilWeight = 0.1f;
}
}
else
{
if (bAiming || bReloading || bEquipping)
{
RecoilWeight = 1.f;
}
else
{
RecoilWeight = 0.5f;
}
}
}
}
void UShooterAnimInstance::Lean(float DeltaTime)
{
if (!ShooterCharacter) return;
CharacterRotationLastFrame = CharacterRotation;
CharacterRotation = ShooterCharacter->GetActorRotation();
const FRotator Delta { UKismetMathLibrary::NormalizedDeltaRotator(CharacterRotation, CharacterRotationLastFrame) };
const double Target { Delta.Yaw / DeltaTime };
const double Interp { FMath::FInterpTo(YawDelta, Target, DeltaTime, 6.f) };
YawDelta = FMath::Clamp(Interp, -90.f, 90.f);
// if (GEngine)
// {
// GEngine->AddOnScreenDebugMessage(
// 3,
// -1,
// FColor::Cyan,
// FString::Printf(TEXT("YawDelta: %f"), YawDelta)
// );
// }
}