Section 8: Advanced Movement - Lecture 124

Crouching Turn Animations
This commit is contained in:
charnet3d 2023-04-22 08:26:18 +00:00
parent 56fad37200
commit 82692124a4
29 changed files with 208 additions and 36 deletions

View File

@ -88,6 +88,8 @@ DoubleClickTime=0.200000
+ActionMappings=(ActionName="Select",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_FaceButton_Right)
+ActionMappings=(ActionName="Reload",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=R)
+ActionMappings=(ActionName="Reload",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_FaceButton_Left)
+ActionMappings=(ActionName="Crouch",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=C)
+ActionMappings=(ActionName="Crouch",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_RightThumbstick)
+AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=W)
+AxisMappings=(AxisName="MoveForward",Scale=-1.000000,Key=S)
+AxisMappings=(AxisName="MoveForward",Scale=1.000000,Key=Gamepad_LeftY)

BIN
Content/_Game/Character/Animations/AimingAimOffset.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/_Game/Character/Animations/HipAimOffset.uasset (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/_Game/Maps/DefaultMap.umap (Stored with Git LFS)

Binary file not shown.

View File

@ -14,9 +14,15 @@ UShooterAnimInstance::UShooterAnimInstance() :
MovementOffsetYaw(0.f),
LastMovementOffsetYaw(0.f),
bAiming(false),
CharacterYaw(0.f),
CharacterYawLastFrame(0.f),
RootYawOffset(0.f)
TIPCharacterYaw(0.f),
TIPCharacterYawLastFrame(0.f),
RootYawOffset(0.f),
Pitch(0.f),
bReloading(false),
OffsetState(EOffsetState::EOS_Hip),
CharacterRotation(FRotator(0)),
CharacterRotationLastFrame(FRotator(0)),
YawDelta(0.f)
{
}
@ -27,7 +33,8 @@ void UShooterAnimInstance::UpdateAnimationProperties(float DeltaTime)
if (!ShooterCharacter) return;
// Get the speed of the character from velocity
// Get the lateral speed of the character from velocity
FVector Velocity{ ShooterCharacter->GetVelocity() };
Velocity.Z = 0;
Speed = Velocity.Size();
@ -49,8 +56,28 @@ void UShooterAnimInstance::UpdateAnimationProperties(float DeltaTime)
}
bAiming = ShooterCharacter->GetAiming();
bReloading = ShooterCharacter->GetCombatState() == ECombatState::ECS_Reloading;
bCrouching = ShooterCharacter->IsCrouching();
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;
}
TurnInPlace();
Lean(DeltaTime);
}
void UShooterAnimInstance::NativeInitializeAnimation()
@ -63,23 +90,26 @@ void UShooterAnimInstance::NativeInitializeAnimation()
void UShooterAnimInstance::TurnInPlace()
{
if (!ShooterCharacter) return;
if (Speed > 0)
Pitch = ShooterCharacter->GetBaseAimRotation().Pitch;
if (Speed > 0 || bIsInAir)
{
// Don't want to turn in place; Character is moving
RootYawOffset = 0.f;
CharacterYaw = ShooterCharacter->GetActorRotation().Yaw;
CharacterYawLastFrame = CharacterYaw;
TIPCharacterYaw = ShooterCharacter->GetActorRotation().Yaw;
TIPCharacterYawLastFrame = TIPCharacterYaw;
RotationCurve = 0.f;
RotationCurveLastFrame = 0.f;
}
else
{
CharacterYawLastFrame = CharacterYaw;
CharacterYaw = ShooterCharacter->GetActorRotation().Yaw;
const float YawDelta { CharacterYaw - CharacterYawLastFrame };
TIPCharacterYawLastFrame = TIPCharacterYaw;
TIPCharacterYaw = ShooterCharacter->GetActorRotation().Yaw;
const float TIPYawDelta { TIPCharacterYaw - TIPCharacterYawLastFrame };
// Root Yaw Offset, updated and clamped to [-180, 180]
RootYawOffset = UKismetMathLibrary::NormalizeAxis(RootYawOffset - YawDelta);
RootYawOffset = UKismetMathLibrary::NormalizeAxis(RootYawOffset - TIPYawDelta);
// 1.0 if turning, 0.0 if not
const float Turning { GetCurveValue(TEXT("Turning")) };
@ -99,14 +129,28 @@ void UShooterAnimInstance::TurnInPlace()
RootYawOffset > 0 ? RootYawOffset -= YawExcess : RootYawOffset += YawExcess;
}
}
}
}
/*if (GEngine)
void UShooterAnimInstance::Lean(float DeltaTime)
{
GEngine->AddOnScreenDebugMessage(1, -1, FColor::Blue,
FString::Printf(TEXT("CharacterYaw: %f"), CharacterYaw));
if (!ShooterCharacter) return;
GEngine->AddOnScreenDebugMessage(2, -1, FColor::Red,
FString::Printf(TEXT("RootYawOffset: %f"), RootYawOffset));
}*/
}
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)
// );
// }
}

View File

@ -7,6 +7,19 @@
#include "ShooterAnimInstance.generated.h"
class AShooterCharacter;
UENUM(BlueprintType)
enum class EOffsetState : uint8
{
EOS_Aiming UMETA(DisplayName = "Aiming"),
EOS_Hip UMETA(DisplayName = "Hip"),
EOS_Reloading UMETA(DisplayName = "Reloading"),
EOS_InAir UMETA(DisplayName = "InAir"),
EOS_MAX UMETA(DisplayName = "DefaultMax")
};
/**
*
*/
@ -27,6 +40,9 @@ public:
protected:
/** Handle turning in place variables */
void TurnInPlace();
/** Handle calculations for leaning while running */
void Lean(float DeltaTime);
private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Movement, meta = (AllowPrivateAccess = true))
@ -55,11 +71,11 @@ private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Movement, meta = (AllowPrivateAccess = true))
bool bAiming;
/** Yaw of the character this frame */
float CharacterYaw;
/** Turn In Place: Yaw of the character this frame; Only updated when standing still and not in the air */
float TIPCharacterYaw;
/** Yaw of the character the previous frame */
float CharacterYawLastFrame;
/** Turn In Place: Yaw of the character the previous frame; Only updated when standing still and not in the air */
float TIPCharacterYawLastFrame;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Turn In Place", meta = (AllowPrivateAccess = true))
float RootYawOffset;
@ -69,4 +85,30 @@ private:
/** Rotation curve value last frame */
float RotationCurveLastFrame;
/** The pitch of the aim rotation used for aim offset */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Turn In Place", meta = (AllowPrivateAccess = true))
float Pitch;
/** True when reloading, used to prevent aim offset when reloading */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Turn In Place", meta = (AllowPrivateAccess = true))
bool bReloading;
/** Offset state; used to determine which Aim Offset to use */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Turn In Place", meta = (AllowPrivateAccess = true))
EOffsetState OffsetState;
/** Yaw of the character this frame */
FRotator CharacterRotation;
/** Yaw of the character the previous frame */
FRotator CharacterRotationLastFrame;
/** Yaw delta used for leaning while running in the blendspace */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Lean", meta = (AllowPrivateAccess = true))
double YawDelta;
/** True when crouching */
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Crouching", meta = (AllowPrivateAccess = true))
bool bCrouching;
};

View File

@ -60,7 +60,8 @@ AShooterCharacter::AShooterCharacter() :
Starting9mmAmmo(85),
StartingARAmmo(120),
// Combat variables
CombatState(ECombatState::ECS_Unoccupied)
CombatState(ECombatState::ECS_Unoccupied),
bCrouching(false)
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
@ -149,6 +150,9 @@ void AShooterCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputCo
PlayerInputComponent->BindAction("Reload", IE_Pressed, this,
&AShooterCharacter::ReloadButtonPressed);
PlayerInputComponent->BindAction("Crouch", IE_Pressed, this,
&AShooterCharacter::CrouchButtonPressed);
}
// Called every frame
@ -686,7 +690,7 @@ void AShooterCharacter::ReloadWeapon()
if (!EquippedWeapon) return;
// Do we have ammo for the correct type
if (CarryingAmmo() && EquippedWeapon->GetAmmo() < EquippedWeapon->GetMagazineCapacity())
if (CarryingAmmo() && !EquippedWeapon->ClipIsFull())
{
CombatState = ECombatState::ECS_Reloading;
UAnimInstance* AnimInstance = GetMesh()->GetAnimInstance();
@ -759,3 +763,11 @@ void AShooterCharacter::ReleaseClip()
{
EquippedWeapon->SetMovingClip(false);
}
void AShooterCharacter::CrouchButtonPressed()
{
if (!GetCharacterMovement()->IsFalling())
{
bCrouching = !bCrouching;
}
}

View File

@ -161,6 +161,9 @@ protected:
/** Called from Animation Blueprint with ReleaseClip notify */
UFUNCTION(BlueprintCallable)
void ReleaseClip();
void CrouchButtonPressed();
private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = true))
USpringArmComponent* CameraBoom;
@ -338,6 +341,10 @@ private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Combat, meta = (AllowPrivateAccess = true))
USceneComponent* HandSceneComponent;
/** True when crouching */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Movement, meta = (AllowPrivateAccess = true))
bool bCrouching;
public:
/* Returns CameraBoom SubObject */
FORCEINLINE USpringArmComponent* GetCameraBoom() const { return CameraBoom; }
@ -358,4 +365,8 @@ public:
FVector GetCameraInterpLocation();
void GetPickupItem(AItem* Item);
FORCEINLINE ECombatState GetCombatState() const { return CombatState; }
FORCEINLINE bool IsCrouching() const { return bCrouching; }
};

View File

@ -65,6 +65,11 @@ void AWeapon::ReloadAmmo(int32 Amount)
Ammo += Amount;
}
bool AWeapon::ClipIsFull()
{
return Ammo >= MagazineCapacity;
}
void AWeapon::StopFalling()
{
bFalling = false;

View File

@ -86,4 +86,6 @@ public:
void ReloadAmmo(int32 Amount);
FORCEINLINE void SetMovingClip(bool Move) { bMovingClip = Move; };
bool ClipIsFull();
};