diff --git a/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/BS_Common_WalkRun_Loop.uasset b/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/BS_Common_WalkRun_Loop.uasset index e52fe04..47921b5 100644 --- a/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/BS_Common_WalkRun_Loop.uasset +++ b/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/BS_Common_WalkRun_Loop.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4f6d008c77aabd1dbdd37490b3c5c90c2c3958960552b6c5ab9d2cd01e3ef39 -size 96903 +oid sha256:54fcc28cf0198b65c51169a7f067d813632c802746a999c65d5bd399d325e3eb +size 97614 diff --git a/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_B_Montage.uasset b/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_B_Montage.uasset index 30d8aae..0b5dc3d 100644 --- a/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_B_Montage.uasset +++ b/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_B_Montage.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f0c7f3d669a02e5aa92f6a05c78124728b26c359bac3db6c2b28dade2d9e7b41 -size 100764 +oid sha256:da6d7b3ae36fd5309a6d31b69cbc6406238e8ed8845d80936c86fa62cfa3520f +size 100671 diff --git a/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_F_Montage.uasset b/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_F_Montage.uasset index 5073344..7099ef8 100644 --- a/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_F_Montage.uasset +++ b/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_F_Montage.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ccab3e0fb6616e4ddaeb0da25825610a46836e70be76a2f41f07673509dbcbd4 -size 100764 +oid sha256:0c4ad86b963a95e8be3350fb90318f833d7ad667106a05342b0baded036d44a1 +size 100671 diff --git a/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_Montage.uasset b/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_Montage.uasset index 72d613c..5aa3f5e 100644 --- a/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_Montage.uasset +++ b/SwordNGun/Content/Characters/Protagonist/Animations/Locomotion/Common/Fighter_Jump_Montage.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:dadd70b91847df21e536ec5c8de76ba663ba16c562b3a101d57edac935d12fc2 -size 100951 +oid sha256:d9b1d7cb7cfc727716a4636c6b5cf8735758c197b4a1b601d1b5255271d53f08 +size 100999 diff --git a/SwordNGun/Content/Characters/Protagonist/Animations/NewProtag_AnimBP.uasset b/SwordNGun/Content/Characters/Protagonist/Animations/NewProtag_AnimBP.uasset index 4696939..470eae5 100644 --- a/SwordNGun/Content/Characters/Protagonist/Animations/NewProtag_AnimBP.uasset +++ b/SwordNGun/Content/Characters/Protagonist/Animations/NewProtag_AnimBP.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d96495d49da6cd90b87abda3e2b5681d9353cf7aa27c29a2c10271a5914b9d1f -size 310300 +oid sha256:57a0520d59e75d352939ce848b9bd75a7e3490b882d6620a894008a659d8d9c2 +size 345340 diff --git a/SwordNGun/Content/Characters/Protagonist/BP_NewProtag.uasset b/SwordNGun/Content/Characters/Protagonist/BP_NewProtag.uasset index 3f2ff71..9b3d6c3 100644 --- a/SwordNGun/Content/Characters/Protagonist/BP_NewProtag.uasset +++ b/SwordNGun/Content/Characters/Protagonist/BP_NewProtag.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6a90b66adb30d17f9a18723e149d2cd553020d021ade8ab5b70c3fa478947682 -size 120934 +oid sha256:7ecb5a7f85bd3012a863b9a712189a6a5245d669698e0b489aad709b60560b85 +size 121112 diff --git a/SwordNGun/Content/Maps/MovementTest.umap b/SwordNGun/Content/Maps/MovementTest.umap index d130c7b..818d791 100644 --- a/SwordNGun/Content/Maps/MovementTest.umap +++ b/SwordNGun/Content/Maps/MovementTest.umap @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:26fd6b912a81b407319afe9584efe86e9cbb9c364423f99b1fd94d2333d13584 +oid sha256:4b75dd510229676eaba5ff8351430835c51ceedb672d6ef2914472fb85dea1d0 size 949560 diff --git a/SwordNGun/Source/SwordNGun/Private/Characters/SNGCharacterBase.cpp b/SwordNGun/Source/SwordNGun/Private/Characters/SNGCharacterBase.cpp index 29b8a2a..f70dda7 100644 --- a/SwordNGun/Source/SwordNGun/Private/Characters/SNGCharacterBase.cpp +++ b/SwordNGun/Source/SwordNGun/Private/Characters/SNGCharacterBase.cpp @@ -11,12 +11,33 @@ #include "Kismet/KismetMathLibrary.h" -static int32 ShowCharacterMovementDebug = 0; -FAutoConsoleVariableRef CVARShowCharacterMovementDebug(TEXT("SNG.ShowCharacterMovementDebug"), - ShowCharacterMovementDebug, +static int32 CharacterMovementDebug = 0; +FAutoConsoleVariableRef CVARCharacterMovementDebug(TEXT("SNG.CharacterMovementDebug.Show"), + CharacterMovementDebug, TEXT("Print movement information for character"), ECVF_Cheat); +static int32 ShowCharacterTrajectory = 0; +FAutoConsoleVariableRef CVARShowCharacterTrajectory(TEXT("SNG.CharacterMovementDebug.Trajectory.Show"), + ShowCharacterTrajectory, + TEXT("Render character trajectory"), + ECVF_Cheat); + +static float TrajectoryPeriod = 0.05f; +FAutoConsoleVariableRef CVARTrajectoryPeriod(TEXT("SNG.CharacterMovementDebug.Trajectory.Period"), + TrajectoryPeriod, + TEXT("How often should trajectory lines be drawn"), + ECVF_Cheat); + +static float TrajectoryLineLifetime = 10.0f; +FAutoConsoleVariableRef CVARTrajectoryLineLifetime(TEXT("SNG.CharacterMovementDebug.Trajectory.Lifetime"), + TrajectoryLineLifetime, + TEXT("How long should a trajectory line segment be visible"), + ECVF_Cheat); + +static float LastSavedPosTime = 0.0f; +static FVector LastSavedPos = FVector::ZeroVector; + // Sets default values ASNGCharacterBase::ASNGCharacterBase(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer.SetDefaultSubobjectClass(ACharacter::CharacterMovementComponentName)) @@ -48,6 +69,11 @@ ASNGCharacterBase::ASNGCharacterBase(const FObjectInitializer& ObjectInitializer { UE_LOG(LogTemp, Warning, TEXT("SNGCharacterBase :: Could not get skeletal mesh. Did you forget to set it?")); } + + + DefaultFOV = 90.0f; + SprintFOV = 110.0f; + SprintFOVInterpSpeed = 2.0f; } void ASNGCharacterBase::MoveForward(float Value) @@ -162,19 +188,48 @@ void ASNGCharacterBase::Tick(float DeltaTime) { Super::Tick(DeltaTime); - if(ShowCharacterMovementDebug) + USNGCharacterMovementComponent* CharMovement = Cast(GetCharacterMovement()); + check(CharMovement); + // interpolate to appropriate field of view depending on whether player sprinting or not + float TargetFOV = CharMovement->GetIsSprinting() ? SprintFOV : DefaultFOV; + float NewFOV = FMath::FInterpTo(CameraComponent->FieldOfView, TargetFOV, DeltaTime, SprintFOVInterpSpeed); + CameraComponent->SetFieldOfView(NewFOV); + + // Debug + if(CharacterMovementDebug) { - FVector StartPos = GetActorLocation() - GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); + FVector StartPos(GetActorLocation().X, + GetActorLocation().Y, + GetActorLocation().Z - GetCapsuleComponent()->GetScaledCapsuleHalfHeight()); FVector ActorForward = UKismetMathLibrary::GetForwardVector(GetActorRotation()); DrawDebugDirectionalArrow(GetWorld(), StartPos, StartPos + (ActorForward * 100.0f), - 10.0f, FColor::Cyan, false, -1.0f, 0, 2.0f); + 10.0f, FColor::Blue, false, -1.0f, 0, 2.0f); FVector CurrInputDirection = GetInputAsWorldDirection(); CurrInputDirection.Normalize(); DrawDebugDirectionalArrow(GetWorld(), StartPos, StartPos + (CurrInputDirection * 100.0f), - 10.0f, FColor::Magenta, false, -1.0f, 0, 2.0f); + 10.0f, FColor::Purple, false, -1.0f, 0, 2.0f); + + FString DebugMsg = FString::Printf(TEXT("MaxWalkSpeed: %f"), GetCharacterMovement()->MaxWalkSpeed); + GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Magenta, DebugMsg); + + float LateralSpeed = GetVelocity().Size2D(); + DebugMsg = FString::Printf(TEXT("LateralSpeed: %f"), LateralSpeed); + GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Magenta, DebugMsg); + + DebugMsg = FString::Printf(TEXT("RotationRate: %s"), *GetCharacterMovement()->RotationRate.ToString()); + GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Magenta, DebugMsg); + + if(ShowCharacterTrajectory) + { + if(GetWorld()->TimeSeconds - LastSavedPosTime >= TrajectoryPeriod) + { + DrawDebugLine(GetWorld(), LastSavedPos, StartPos, FColor::Red, false, TrajectoryLineLifetime, 0, 2.0f); + LastSavedPos = StartPos; + LastSavedPosTime = GetWorld()->TimeSeconds; + } + } } - } // Called to bind functionality to input diff --git a/SwordNGun/Source/SwordNGun/Private/Components/SNGCharacterMovementComponent.cpp b/SwordNGun/Source/SwordNGun/Private/Components/SNGCharacterMovementComponent.cpp index f07388f..f30e7ca 100644 --- a/SwordNGun/Source/SwordNGun/Private/Components/SNGCharacterMovementComponent.cpp +++ b/SwordNGun/Source/SwordNGun/Private/Components/SNGCharacterMovementComponent.cpp @@ -3,16 +3,29 @@ #include "Components/SNGCharacterMovementComponent.h" +#include "Kismet/KismetMathLibrary.h" + USNGCharacterMovementComponent::USNGCharacterMovementComponent() { - // Set defaults dealing with grounded movement + // Defaults DefaultGroundFriction = 8.0f; DefaultGravityScale = 1.0f; - DefaultMaxWalkSpeed = 475.0f; - FiringMaxWalkSpeed = 300.0f; - ReloadingMaxWalkSpeed = 300.0f; - SprintingMaxWalkSpeed = 600.0f; + DefaultMaxWalkSpeed = 600.0f; + DefaultRotationRate = FRotator(0.0f, 360.0f, 0.0f); + + // sprint + SprintingMaxWalkSpeed = 800.0f; + SprintLateralSpeedThreshold = 300.0f; + SprintingRotationRate = FRotator(0.0f, 180.0f, 0.0f); + TimeToInitiateSprint = 4.0f; + WalkToSprintInterpSpeed = 1.0f; + // firing + FiringMaxWalkSpeed = 300.0f; + + // reloading + ReloadingMaxWalkSpeed = 300.0f; + // Set defaults dealing with jumping and being airborne DefaultJumpForce = 1000.0f; DefaultAirFriction = 150.0f; @@ -35,12 +48,18 @@ void USNGCharacterMovementComponent::RestoreMovementDefaults() { GroundFriction = DefaultGroundFriction; GravityScale = DefaultGravityScale; + RotationRate = DefaultRotationRate; MaxWalkSpeed = DefaultMaxWalkSpeed; BrakingDecelerationFalling = DefaultAirFriction; AirControl = DefaultAirControl; JumpZVelocity = DefaultJumpForce; } +void USNGCharacterMovementComponent::OnSprintTimer() +{ + bIsSprinting = true; +} + void USNGCharacterMovementComponent::StartJump() { /* @@ -75,5 +94,31 @@ void USNGCharacterMovementComponent::TickComponent(float DeltaTime, ELevelTick T { Super::TickComponent(DeltaTime, Tick, ThisTickFunction); + float LateralSpeed = Velocity.Size2D(); + if(LateralSpeed >= SprintLateralSpeedThreshold && !GetWorld()->GetTimerManager().IsTimerActive(TimerHandle_SprintTimer) ) + { + GetWorld()->GetTimerManager().SetTimer(TimerHandle_SprintTimer, + this, &USNGCharacterMovementComponent::OnSprintTimer, + TimeToInitiateSprint, false); + } + + if(LateralSpeed < SprintLateralSpeedThreshold && GetWorld()->GetTimerManager().IsTimerActive(TimerHandle_SprintTimer)) + { + GetWorld()->GetTimerManager().ClearTimer(TimerHandle_SprintTimer); + bIsSprinting = false; + } + // set walk speed and rotation rate depending on whether player is sprinting or not + float TargetMaxWalkSpeed = bIsSprinting ? SprintingMaxWalkSpeed : DefaultMaxWalkSpeed; + float NewMaxWalkSpeed = FMath::FInterpTo(MaxWalkSpeed, TargetMaxWalkSpeed, DeltaTime, WalkToSprintInterpSpeed); + MaxWalkSpeed = NewMaxWalkSpeed; + + // NOTE(kevin): since default rotate rate is 360 RInterpTo will go from 0 to 180 instead of 360 to 180 + // need to think of a way to prevent this + // might just need to do my own interp manually + /* + FRotator TargetRotationRate = bIsSprinting ? SprintingRotationRate : DefaultRotationRate; + FRotator NewRotationRate = FMath::RInterpTo(RotationRate, TargetRotationRate, DeltaTime, WalkToSprintInterpSpeed); + RotationRate = NewRotationRate; + */ } diff --git a/SwordNGun/Source/SwordNGun/Public/Characters/SNGCharacterBase.h b/SwordNGun/Source/SwordNGun/Public/Characters/SNGCharacterBase.h index ca333a2..450639c 100644 --- a/SwordNGun/Source/SwordNGun/Public/Characters/SNGCharacterBase.h +++ b/SwordNGun/Source/SwordNGun/Public/Characters/SNGCharacterBase.h @@ -42,6 +42,18 @@ protected: UPROPERTY(BlueprintReadWrite) bool CanMovementCancelMontage; + + /** Field of the view the camera starts with */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Field Of View", meta=(ClampMin="30", UIMin="30")) + float DefaultFOV; + + /** Field of the view when the player starts sprinting */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Field Of View", meta=(ClampMin="30", UIMin="30")) + float SprintFOV; + + /** */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Field Of View", meta=(ClampMin="0", UIMin="0")) + float SprintFOVInterpSpeed; void MoveForward(float Value); diff --git a/SwordNGun/Source/SwordNGun/Public/Components/SNGCharacterMovementComponent.h b/SwordNGun/Source/SwordNGun/Public/Components/SNGCharacterMovementComponent.h index 8fa5cce..10f2985 100644 --- a/SwordNGun/Source/SwordNGun/Public/Components/SNGCharacterMovementComponent.h +++ b/SwordNGun/Source/SwordNGun/Public/Components/SNGCharacterMovementComponent.h @@ -27,45 +27,83 @@ public: UFUNCTION(BlueprintCallable) void RestoreMovementDefaults(); + /** + * Gets bool whether the character is currently in the sprinting state + */ + UFUNCTION(BlueprintCallable) + FORCEINLINE bool GetIsSprinting() { return bIsSprinting; } + protected: + // default ground /** Default friction when not performing any special actions and on the ground */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Ground Defaults", meta=(ClampMin="0", UIMin="0")) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Ground.Defaults", meta=(ClampMin="0", UIMin="0")) float DefaultGroundFriction; /** Default ground walk speed when not performing any special actions */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Ground Defaults", meta=(ClampMin="0", UIMin="0")) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Ground.Defaults", meta=(ClampMin="0", UIMin="0")) float DefaultMaxWalkSpeed; - /** Ground walk speed when firing a ranged weapon */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Ground Defaults", meta=(ClampMin="0", UIMin="0")) - float FiringMaxWalkSpeed; - - /** Ground walk speed when reloading a ranged weapon */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Ground Defaults", meta=(ClampMin="0", UIMin="0")) - float ReloadingMaxWalkSpeed; - + /** Default ground walk speed when not performing any special actions */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Ground.Defaults", meta=(ClampMin="0", UIMin="0")) + FRotator DefaultRotationRate; + + // sprinting /** Ground walk speed when sprinting */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Ground Defaults", meta=(ClampMin="0", UIMin="0")) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Ground.Sprint", meta=(ClampMin="0", UIMin="0")) float SprintingMaxWalkSpeed; + /** Lateral speed the player needs to maintain to stay in the sprinting state */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Ground.Sprint", meta=(ClampMin="0", UIMin="0")) + float SprintLateralSpeedThreshold; + + /** Default ground walk speed when not performing any special actions */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Ground.Sprint", meta=(ClampMin="0", UIMin="0")) + FRotator SprintingRotationRate; + + /** How long after applying movement input should the character start sprinting? */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Ground.Sprint", meta=(ClampMin="0", UIMin="0")) + float TimeToInitiateSprint; + + /** The speed in which the max walk speed to interpolated to the max sprint speed when a sprint has been initiated */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Ground.Sprint", meta=(ClampMin="0", UIMin="0")) + float WalkToSprintInterpSpeed; + + FTimerHandle TimerHandle_SprintTimer; + + UPROPERTY(BlueprintReadOnly) + bool bIsSprinting; + + void OnSprintTimer(); + + // firing + /** Ground walk speed when firing a ranged weapon */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Firing", meta=(ClampMin="0", UIMin="0")) + float FiringMaxWalkSpeed; + + // reloading + /** Ground walk speed when reloading a ranged weapon */ + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Reloading", meta=(ClampMin="0", UIMin="0")) + float ReloadingMaxWalkSpeed; + + // airborne /** Gravity scale when not performing any special actions */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Air Defaults", meta=(ClampMin="0", UIMin="0")) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Air.Defaults", meta=(ClampMin="0", UIMin="0")) float DefaultGravityScale; /** Force to continuously apply to character when they are holding the jump button */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Air Defaults", meta=(ClampMin="0", UIMin="0")) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Air.Defaults", meta=(ClampMin="0", UIMin="0")) float DefaultJumpForce; /** Minimum height a character must reach before jump force is no longer applied even if the jump input is not being held */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Air Defaults", meta=(ClampMin="0", UIMin="0")) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Air.Defaults", meta=(ClampMin="0", UIMin="0")) float MinJumpHeight; /** Max time the jump button can be held to give character upward velocity */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Air Defaults", meta=(ClampMin="0", UIMin="0")) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Air.Defaults", meta=(ClampMin="0", UIMin="0")) float MaxJumpTime; /** How much to dampen lateral velocities at the start of a jump */ - UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Character Movement: SNG Air Defaults", meta=(ClampMin="0", UIMin="0")) + UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="SNG Character Movement.Air.Defaults", meta=(ClampMin="0", UIMin="0")) float LateralVelocityDampening; /**