diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index 09ddd8d..3ef1e4d 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -73,4 +73,5 @@ GlobalDefaultServerGameMode=None +PropertyRedirects=(OldName="/Script/Exo.ExoPlayerCharacter.CoverEyeHeight",NewName="/Script/Exo.ExoPlayerCharacter.LowEyeHeight") +FunctionRedirects=(OldName="/Script/Exo.ExoPlayerController.CalculateCoverAim",NewName="/Script/Exo.ExoPlayerController.CalculateCoverAimOffset") +PropertyRedirects=(OldName="/Script/Exo.ExoPlayerController.UseEyeHeight",NewName="/Script/Exo.ExoPlayerController.bUseEyeHeight") -+FunctionRedirects=(OldName="/Script/Exo.ExoPlayerCharacter.SetEyePositionOffset",NewName="/Script/Exo.ExoPlayerCharacter.SetEyePositionOffsetTarget") \ No newline at end of file ++FunctionRedirects=(OldName="/Script/Exo.ExoPlayerCharacter.SetEyePositionOffset",NewName="/Script/Exo.ExoPlayerCharacter.SetEyePositionOffsetTarget") ++FunctionRedirects=(OldName="/Script/Exo.ExoPlayerCharacter.UnCrouchCustom",NewName="/Script/Exo.ExoPlayerCharacter.TryUnCrouchCustom") \ No newline at end of file diff --git a/Content/Blueprints/Characters/Player/BP_ExoPlayerCharacter.uasset b/Content/Blueprints/Characters/Player/BP_ExoPlayerCharacter.uasset index 35df021..45020c5 100644 Binary files a/Content/Blueprints/Characters/Player/BP_ExoPlayerCharacter.uasset and b/Content/Blueprints/Characters/Player/BP_ExoPlayerCharacter.uasset differ diff --git a/Content/Levels/TestMap.umap b/Content/Levels/TestMap.umap index 7b13708..698af01 100644 Binary files a/Content/Levels/TestMap.umap and b/Content/Levels/TestMap.umap differ diff --git a/Source/Exo/Private/Characters/ExoPlayerCharacter.cpp b/Source/Exo/Private/Characters/ExoPlayerCharacter.cpp index 7e57e0e..783df44 100644 --- a/Source/Exo/Private/Characters/ExoPlayerCharacter.cpp +++ b/Source/Exo/Private/Characters/ExoPlayerCharacter.cpp @@ -60,7 +60,6 @@ void AExoPlayerCharacter::BeginPlay() CameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, FromFeet(TargetEyeHeight))); GetCapsuleComponent()->OnComponentBeginOverlap.AddDynamic(this, &AExoPlayerCharacter::OnActorBeginOverlap); - //UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0)->SetViewTarget(this); PlayerHud = CreateWidget(GetWorld(),PlayerHudClass); @@ -83,12 +82,6 @@ void AExoPlayerCharacter::BeginPlay() void AExoPlayerCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); - - //// NOT FINAL SOLUTION /// - /** Reset camera offset at the start of every frame */ - //TargetEyeLocationOffset = FVector::ZeroVector; - //TargetEyeRoll = 0.f; - ////////////////////////// UpdateCameraHeight(DeltaTime); ApplyCameraOffsets(DeltaTime); @@ -115,11 +108,6 @@ void AExoPlayerCharacter::UpdateCameraHeight(float DeltaTime) void AExoPlayerCharacter::ApplyCameraOffsets(float DeltaTime) { bool HasChanged = false; - //FVector NewOffset = EyeLocationOffset; - //FVector NoOffsetCameraPosition = FVector(0, 0, EyeHeight); - //FVector NoOffsetCameraPosition = CameraComponent->GetRelativeLocation() - EyeLocationOffset; - //UE_LOG(LogTemp, Log, TEXT("%s"), *NoOffsetCameraPosition.ToString()); - if (!FVector::PointsAreNear(EyeLocationOffset, TargetEyeLocationOffset, 0.01f)) { // Smoothly offset view @@ -141,15 +129,10 @@ void AExoPlayerCharacter::ApplyCameraOffsets(float DeltaTime) } // Update actual camera position - //FVector BaseLocation = FVector(0, 0, GetCurrentEyeHeightBase(true)); - //CameraComponent->SetRelativeLocation(NoOffsetCameraPosition + NewOffset); - //FVector CapsuleRelativeOffset = BaseLocation + EyeLocationOffset; - //CapsuleRelativeOffset.Z += GetCurrentEyeHeightBase(true); const FVector FinalOffset = FVector(EyeLocationOffset.X, EyeLocationOffset.Y, EyeLocationOffset.Z + TargetEyeHeight + GetFootOffset()); CameraComponent->SetRelativeLocation(FinalOffset); - - //UE_LOG(LogTemp, Log, TEXT("Camera relative: %s"), *CameraComponent->GetRelativeLocation().ToString()); + // Update actual camera rotation (Roll) FRotator NewRotator = GetController()->GetControlRotation(); NewRotator.Roll = EyeRoll; @@ -192,21 +175,22 @@ void AExoPlayerCharacter::CrouchCustom() { SetTargetEyeHeight(CrouchedEyeHeight); GetCharacterMovement()->MaxWalkSpeed = CrouchSpeed; + bIsCrouched = true; float CurrentCamHeight = GetCurrentEyeHeight(); - GetCapsuleComponent()->SetCapsuleHalfHeight(44.f); + GetCapsuleComponent()->SetCapsuleHalfHeight(GetCharacterMovement()->CrouchedHalfHeight); CameraComponent->SetRelativeLocation( FVector(0, 0, GetFootOffset()) + FVector(0, 0, CurrentCamHeight)); } -void AExoPlayerCharacter::UnCrouchCustom() +void AExoPlayerCharacter::TryUnCrouchCustom() { SetTargetEyeHeight(StandingEyeHeight); GetCharacterMovement()->MaxWalkSpeed = WalkSpeed; float CurrentCamHeight = GetCurrentEyeHeight(); - GetCapsuleComponent()->SetCapsuleHalfHeight(88.f); + GetCapsuleComponent()->SetCapsuleHalfHeight(StandingHalfHeight); CameraComponent->SetRelativeLocation( FVector(0, 0, GetFootOffset()) + FVector(0, 0, CurrentCamHeight)); @@ -255,6 +239,11 @@ float AExoPlayerCharacter::GetCrouchingEyeHeight(const bool bCapsuleRelative) co : CrouchedEyeHeight; } +bool AExoPlayerCharacter::IsCrouching() const +{ + return bIsCrouched; +} + void AExoPlayerCharacter::SetEyePositionOffsetTarget(const FVector LocationOffset) { diff --git a/Source/Exo/Private/Player/ExoPlayerController.cpp b/Source/Exo/Private/Player/ExoPlayerController.cpp index f064663..a036ab8 100644 --- a/Source/Exo/Private/Player/ExoPlayerController.cpp +++ b/Source/Exo/Private/Player/ExoPlayerController.cpp @@ -36,27 +36,17 @@ void AExoPlayerController::BeginPlay() PlayerCharacter->GetCharacterMovement()->MaxWalkSpeed = PlayerCharacter->WalkSpeed; } -void AExoPlayerController::PlayerTick(float DeltaTime) +void AExoPlayerController::PlayerTick(const float DeltaTime) { Super::PlayerTick(DeltaTime); + bIsCoverAiming = (PlayerCharacter->bIsInCover && PlayerCharacter->bIsAimingMode); - if (PlayerCharacter->bIsInCover) + if (bIsCoverAiming) { - //PlayerCharacter->SetEyePositionOffsetTarget( - // FVector(0, 0, PlayerCharacter->LowEyeHeightOffset) - // ); - if (PlayerCharacter->bIsAimingMode) - { - CoverAimHeightOffset = CalculateCoverAimOffset(); - PlayerCharacter->SetEyePositionOffsetTarget( - FVector(0.f, 0.f, CoverAimHeightOffset)); - } + CoverAimHeightOffset = CalculateCoverAimOffset(); + PlayerCharacter->SetEyePositionOffsetTarget(FVector(0.f, 0.f, CoverAimHeightOffset)); } - //else - //{ - // PlayerCharacter->SetEyePositionOffsetTarget(FVector::ZeroVector); - //} // On screen cover state DEBUG if (bShowCoverSystemDebug) @@ -167,15 +157,8 @@ void AExoPlayerController::PlayerStartCrouch() PlayerCharacter->SetTargetEyeHeight(PlayerCharacter->LowEyeHeightOffset); GetWorldTimerManager().SetTimer(SlideCooldownTimer, this, &AExoPlayerController::ResetSlide, PlayerCharacter->SlideCooldown, false); } - - //PlayerCharacter->Crouch(); + PlayerCharacter->CrouchCustom(); - //PlayerCharacter->SetTargetEyeHeight(PlayerCharacter->CrouchedEyeHeight); - // PlayerCharacter->CameraComponent->SetRelativeLocation(FVector( - // 0.0f, - // 0.0f, - // PlayerCharacter->CrouchedEyeHeight) - // ); // Start checking for cover PlayerCharacter->bIsInCover = CheckForCover(); @@ -190,19 +173,11 @@ void AExoPlayerController::PlayerStartCrouch() void AExoPlayerController::PlayerStopCrouch() { - //PlayerCharacter->UnCrouch(); - PlayerCharacter->UnCrouchCustom(); - //PlayerCharacter->SetTargetEyeHeight(PlayerCharacter->GetStandingEyeHeight()); - // PlayerCharacter->CameraComponent->SetRelativeLocation(FVector( - // 0.0f, - // 0.0f, - // PlayerCharacter->BaseEyeHeight) - // ); + PlayerCharacter->TryUnCrouchCustom(); // Stop checking for cover GetWorld()->GetTimerManager().ClearTimer(CoverCheckTimer); PlayerCharacter->bIsInCover = false; - TargetCoverStandAlpha = 0.0f; } void AExoPlayerController::ResetSlide() @@ -253,7 +228,7 @@ void AExoPlayerController::PlayerStopAim() ShootingComponent->StopAiming(); if (PlayerCharacter->bIsInCover) { - CalculateCoverAimOffset(); + PlayerCharacter->SetEyePositionOffsetTarget(FVector(0, 0, 0)); } } @@ -289,9 +264,6 @@ void AExoPlayerController::PlayerReload() bool AExoPlayerController::CheckForCover() { - // Cover is recalculated every time the player crouches or stops moving while crouched - // Cover targets are cleared completely when player stands up again or dies - // Do a simple 8-directional line trace FVector TraceDirection = PlayerCharacter->GetActorForwardVector(); FVector TraceStart = PlayerCharacter->GetActorLocation(); @@ -372,16 +344,6 @@ float AExoPlayerController::CalculateCoverAimOffset() // Oblicz maksymalną wysokość, na którą można wychylić się znad osłony MaxCoverAimHeight = PlayerCharacter->GetStandingEyeHeight() * CoverAimStandFactor; - - FVector ObstacleTraceStart = GetCharacter()->GetActorLocation(); - ObstacleTraceStart.Z += - bUseEyeHeight ? - PlayerCharacter->GetCurrentEyeHeight(true) - : - PlayerCharacter->CrouchedEyeHeight - GetCharacter()->GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); - - FVector ObstacleTraceEnd = - ObstacleTraceStart + PlayerCameraManager->GetCameraRotation().Vector() * CoverAimFreeDistance; FCollisionQueryParams QueryParams; QueryParams.AddIgnoredActor(PlayerCharacter); @@ -390,40 +352,9 @@ float AExoPlayerController::CalculateCoverAimOffset() FHitResult Hit; bool bFreeSpace = false; - // SphereTrace until no hit is found (free space to aim) - // for (int i = 0; i < MaxCoverAimHeight; i += CoverAimWindowRadius) - // { - // ObstacleTraceStart.Z += i; - // ObstacleTraceEnd.Z += i; - // - // GetWorld()->SweepSingleByChannel( - // Hit, - // ObstacleTraceStart, - // ObstacleTraceEnd, - // FQuat::Identity, - // ObstacleTraceChannel, - // FCollisionShape::MakeSphere(CoverAimWindowRadius), - // QueryParams - // ); - // - // if (bShowCoverSystemDebug) - // { - // DrawDebugSphere(GetWorld(), Hit.Location, CoverAimWindowRadius, 8, - // Hit.bBlockingHit ? FColor::Blue : FColor::Red, - // false, 0.0f, 0, 0); - // } - // - // if (Hit.bBlockingHit == false) - // { - // UE_LOG(LogTemp, Display, TEXT("Free space")); - // bFreeSpace = true; - // break; - // } - // } - - ObstacleTraceStart = PlayerCharacter->GetPlayerLocationAtFeet(); + FVector ObstacleTraceStart = PlayerCharacter->GetPlayerLocationAtFeet(); ObstacleTraceStart.Z += PlayerCharacter->CrouchedEyeHeight; - ObstacleTraceEnd = ObstacleTraceStart + PlayerCameraManager->GetCameraRotation().Vector() * CoverAimFreeDistance; + FVector ObstacleTraceEnd = ObstacleTraceStart + PlayerCameraManager->GetCameraRotation().Vector() * CoverAimFreeDistance; float SafeCoverAimZOffset = 0.f; while (SafeCoverAimZOffset < MaxCoverAimHeight) @@ -457,6 +388,7 @@ float AExoPlayerController::CalculateCoverAimOffset() // If this is true that means that free space was found if (FinalHitHeight <= MaxCoverAimHeight) { + PlayerCharacter->bIsCrouched = false; //// DEBUG //// if (bShowCoverSystemDebug) { @@ -469,44 +401,13 @@ float AExoPlayerController::CalculateCoverAimOffset() } // Return 0 offset if no free space to aim was found - return 0.f; -} - -void AExoPlayerController::UpdateSmoothCoverCamera(float DeltaTime) -{ - if (FMath::IsNearlyEqual(CoverStandAlpha, TargetCoverStandAlpha, 0.01f)) - { - return; - } - - CoverStandAlpha = FMath::Lerp(CoverStandAlpha, TargetCoverStandAlpha, DeltaTime * 5.0f); - - // BANDAID SOLUTION - const float NewZ = FMath::Lerp( - PlayerCharacter->GetCrouchingEyeHeight(), - PlayerCharacter->GetStandingEyeHeight(), - CoverStandAlpha - ); - - PlayerCharacter->CameraComponent->SetRelativeLocation( - FVector(0.0f, 0.0f, NewZ) - ); - - // DEBUG - if (bShowCoverSystemDebug && GEngine) - { - GEngine->AddOnScreenDebugMessage(1, -1, FColor::Red, FString::Printf(TEXT("Current cover stand alpha: %f"), CoverStandAlpha)); - } + //return 0.f; + return MaxCoverAimHeight - PlayerCharacter->CrouchedEyeHeight; } void AExoPlayerController::OnCoverTimer() { PlayerCharacter->bIsInCover = CheckForCover(); - if (PlayerCharacter->bIsInCover == false) - { - TargetCoverStandAlpha = 0.0f; - UpdateSmoothCoverCamera(GetWorld()->GetDeltaSeconds()); - } } void AExoPlayerController::DebugCoverSystem(bool show) diff --git a/Source/Exo/Public/Characters/ExoPlayerCharacter.h b/Source/Exo/Public/Characters/ExoPlayerCharacter.h index ab82e26..8f25f12 100644 --- a/Source/Exo/Public/Characters/ExoPlayerCharacter.h +++ b/Source/Exo/Public/Characters/ExoPlayerCharacter.h @@ -19,6 +19,7 @@ class EXO_API AExoPlayerCharacter : public AExoCharacterBase public: AExoPlayerCharacter(); + /// U PROPERTIES /// UPROPERTY(EditAnywhere, Category = "Combat") TObjectPtr Weapon; @@ -34,6 +35,9 @@ public: UPROPERTY(VisibleAnywhere, BlueprintReadOnly) TObjectPtr CapsuleBottom; + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI") + TSubclassOf PlayerHudClass; + UPROPERTY(EditAnywhere, Category = "Dodge Properties") float DodgeForce = 5000.f; @@ -61,19 +65,35 @@ public: UPROPERTY(EditAnywhere, Category = "Health") float CurrentHealth = 50.0f; - UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "UI") - TSubclassOf PlayerHudClass; + /// Połowa wysokości kapsuły gracza podczas stania + UPROPERTY(EditAnywhere, BlueprintReadOnly) + float StandingHalfHeight = 88.f; + + /** Czy postać gracza jest obecnie schowana za osłoną */ + UPROPERTY(BlueprintReadOnly, Category = "Cover System") + bool bIsInCover = false; + + /** Offset kamery podczas leżenia (osłona, ślizg)
+ * Bezpiecznie będzie założyć że to najniżej jak kamera + * może zejść podczas gameplaya + */ + UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera") + float LowEyeHeightOffset; + + /// U FUNCTIONS /// UFUNCTION() void OnActorBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult ); + /// Przełącza gracza w tryb kucania UFUNCTION(BlueprintCallable, Category = "Movement") void CrouchCustom(); + /// Próbuje wyjść z trybu kucania UFUNCTION(BlueprintCallable, Category = "Movement") - void UnCrouchCustom(); + void TryUnCrouchCustom(); DECLARE_MULTICAST_DELEGATE(FOnPlayerCrouchEvent); FOnPlayerCrouchEvent OnPlayerCrouchStart; @@ -115,17 +135,9 @@ public: UFUNCTION(BlueprintPure, Category="Camera") float GetCrouchingEyeHeight(const bool bCapsuleRelative = false) const; - - /** Czy postać gracza jest obecnie schowana za osłoną */ - UPROPERTY(BlueprintReadOnly, Category = "Cover System") - bool bIsInCover = false; - /** Offset kamery podczas leżenia (osłona, ślizg)
- * Bezpiecznie będzie założyć że to najniżej jak kamera - * może zejść podczas gameplaya - */ - UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Camera") - float LowEyeHeightOffset; + UFUNCTION(BlueprintPure, Category="Movement") + bool IsCrouching() const; protected: diff --git a/Source/Exo/Public/Player/ExoPlayerController.h b/Source/Exo/Public/Player/ExoPlayerController.h index edfe266..0964c22 100644 --- a/Source/Exo/Public/Player/ExoPlayerController.h +++ b/Source/Exo/Public/Player/ExoPlayerController.h @@ -25,6 +25,9 @@ public: virtual void PlayerTick(float DeltaTime) override; + UPROPERTY(BlueprintReadOnly) + bool bIsCoverAiming = false; + protected: virtual void SetupInputComponent() override; @@ -95,13 +98,7 @@ protected: UFUNCTION(BlueprintCallable, Category = "Cover System") bool CheckForCover(); - UFUNCTION(BlueprintCallable, Category = "Cover System") - float CalculateCoverAimOffset(); - - UFUNCTION(BlueprintCallable, Category = "Cover System") - void UpdateSmoothCoverCamera(float DeltaTime); - - void OnCoverTimer(); + //DECLARE_MULTICAST_DELEGATE(FOnPlayerAimEvent); // Cover System DEBUG UFUNCTION(Exec, Category = "Cover System") @@ -175,13 +172,6 @@ protected: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Character") TObjectPtr PlayerCharacter; - /** Alpha wysokości kamery podczas wychulania zza osłony - * 0 - Wysokość kucania - * 1 - Maksymalna wysokość wychylenia określona przez CoverAimStandFactor - **/ - UPROPERTY(EditAnywhere, Category = "Cover System") - float TargetCoverStandAlpha = 0.0f; - /** Częstotliwość okresowego szukania osłon podczas kucania */ UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cover System") float CoverCheckRate = 0.5f; @@ -234,15 +224,10 @@ private: UShootingComponent* ShootingComponent; + float CalculateCoverAimOffset(); + void OnCoverTimer(); - - float CoverStandAlpha = 0.0f; // deprecated FTimerHandle CoverCheckTimer; float MaxCoverAimHeight; float CoverAimHeightOffset; - - - - //FTransform TargetCameraOffset; - //FTransform CameraOffset; };