// Fill out your copyright notice in the Description page of Project Settings. #include "Characters/ExoPlayerCharacter.h" #include "Blueprint/UserWidget.h" #include "Characters/Components/ShootingComponent.h" #include "Components/CapsuleComponent.h" #include "GameFramework/CharacterMovementComponent.h" #include "Items/AmmoBoxBase.h" #include "Items/HealthBoxBase.h" #include "Player/InteractionComponent.h" #include "Widget/WBP_PlayerUI.h" AExoPlayerCharacter::AExoPlayerCharacter() { PrimaryActorTick.bCanEverTick = true; // Setup eye height values StandingEyeHeight = 175.f; CrouchedEyeHeight = 50.f; LowEyeHeightOffset = -20.f; // Create camera component CameraComponent = CreateDefaultSubobject(TEXT("CameraComponent")); CameraComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform); CameraComponent->bUsePawnControlRotation = true; GetCharacterMovement()->bSnapToPlaneAtStart = true; InteractionComponent = CreateDefaultSubobject(TEXT("Interaction Component")); ShootingComponent = CreateDefaultSubobject(TEXT("Shooting Component")); Weapon = CreateDefaultSubobject("Weapon"); Weapon->SetupAttachment(GetMesh()); Weapon->SetCollisionEnabled(ECollisionEnabled::NoCollision); Weapon->bCastDynamicShadow = false; Weapon->CastShadow = false; Weapon->SetRelativeLocation(FVector(-50.f, 0.f, -90.f)); //bUseControllerRotationPitch = false; //bUseControllerRotationYaw = true; //bUseControllerRotationRoll = false; } void AExoPlayerCharacter::BeginPlay() { Super::BeginPlay(); // Set correct starting camera height SetTargetEyeHeight(StandingEyeHeight); CameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, TargetEyeHeight + GetFootOffset())); GetCapsuleComponent()->OnComponentBeginOverlap.AddDynamic(this, &AExoPlayerCharacter::OnActorBeginOverlap); // Setup crouch timeline FOnTimelineFloat ProgressUpdate; ProgressUpdate.BindUFunction(this, FName("CrouchingUpdate")); FOnTimelineEvent FinishedEvent; FinishedEvent.BindUFunction(this, FName("CrouchingFinished")); CrouchTimeline.AddInterpFloat(CapsuleResizeCurve, ProgressUpdate); CrouchTimeline.SetTimelineFinishedFunc(FinishedEvent); PlayerHud = CreateWidget(GetWorld(),PlayerHudClass); if (PlayerHud) { PlayerHud->AddToViewport(); PlayerHud->AddToPlayerScreen(); if (PlayerHud) { PlayerHud->SetHp(CurrentHealth,MaxHealth); PlayerHud->SetAmmoNumber(10); PlayerHud->SetAmmoType(EAmmoType::Revolver); for (int i=0;i<4;i++) PlayerHud->AddBuf(NULL,0.25f*i); PlayerHud->SetVisibilityHP(false); PlayerHud->SetVisibilityBuf(false); PlayerHud->SetVisibilityAmmo(false); PlayerHud->SetVisibilityViewFinder(false); PlayerHud->SetShootingViewFinder(false); } } } void AExoPlayerCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); CrouchTimeline.TickTimeline(DeltaTime); UpdateCameraHeight(DeltaTime); ApplyCameraOffsets(DeltaTime); } float AExoPlayerCharacter::GetFootOffset() { return -GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); } void AExoPlayerCharacter::CrouchingUpdate(float Alpha) { float CurrentCamHeight = GetCurrentEyeHeight(); float NewHalfHeight = FMath::Lerp( StandingHalfHeight, GetCharacterMovement()->CrouchedHalfHeight, Alpha); GetCapsuleComponent()->SetCapsuleHalfHeight(NewHalfHeight); CameraComponent->SetRelativeLocation( FVector(0, 0, GetFootOffset()) + FVector(0, 0, CurrentCamHeight)); UE_LOG(LogTemp, Display, TEXT("Crouching Update")); } void AExoPlayerCharacter::CrouchingFinished() { } void AExoPlayerCharacter::UpdateCameraHeight(float DeltaTime) { //if (FMath::IsNearlyEqual(EyeHeight, TargetEyeHeight, 0.01f)) //{ //CameraComponent->SetRelativeLocation(FVector(0.f, 0.f,EyeHeight)); //return; //} const float LerpDelta = 1.0 - exp(-5 * DeltaTime); EyeHeight = FMath::Lerp(EyeHeight, TargetEyeHeight, LerpDelta); //const FVector CamRelXY = CameraComponent->GetRelativeLocation(); const float RelEyeHeight = GetFootOffset() + EyeHeight; //CameraComponent->SetRelativeLocation(FVector(CamRelXY.X, CamRelXY.Y,EyeHeight)); CameraComponent->SetRelativeLocation(FVector(0.f, 0.f,RelEyeHeight)); } void AExoPlayerCharacter::ApplyCameraOffsets(float DeltaTime) { bool HasChanged = false; const float LerpDelta = 1.0 - exp(-5 * DeltaTime); if (!FVector::PointsAreNear(EyeLocationOffset, TargetEyeLocationOffset, 0.01f)) { // Smoothly offset view EyeLocationOffset = FMath::Lerp(EyeLocationOffset, TargetEyeLocationOffset, LerpDelta); HasChanged = true; } if (!FMath::IsNearlyEqual(EyeRoll, TargetEyeRoll, 0.01f)) { // Smoothly rotate view EyeRoll = FMath::Lerp(EyeRoll, TargetEyeRoll, LerpDelta); HasChanged = true; } if (!HasChanged) { // Do not calculate anything if nothing changed CameraComponent->AddRelativeLocation(EyeLocationOffset); return; } // Update actual camera position const FVector FinalLocation = FVector(EyeLocationOffset.X, EyeLocationOffset.Y, EyeLocationOffset.Z + TargetEyeHeight + GetFootOffset()); CameraComponent->SetRelativeLocation(FinalLocation); // Update actual camera rotation (Roll) FRotator NewRotator = GetController()->GetControlRotation(); NewRotator.Roll = EyeRoll; GetController()->SetControlRotation(NewRotator); } void AExoPlayerCharacter::OnActorBeginOverlap(UPrimitiveComponent* OverlappedComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) { if (OtherActor && OtherActor != this) { if (OtherActor->IsA(AHealthBoxBase::StaticClass())) { AHealthBoxBase* HealthBox = Cast(OtherActor); if (HealthBox) { AddHealthPoints(HealthBox->HealthValue); HealthBox->Destroy(); UE_LOG(LogTemp, Warning, TEXT("Zebrano apteczkę")); } } else if (OtherActor->IsA(AAmmoBoxBase::StaticClass())) { AAmmoBoxBase* AmmoBox = Cast(OtherActor); if (AmmoBox) { if (ShootingComponent->AddAmmo(AmmoBox->AmmoType, AmmoBox->AmmoValue)) { AmmoBox->Destroy(); UE_LOG(LogTemp, Warning, TEXT("Zebrano amunicję")); } } } } } void AExoPlayerCharacter::CrouchCustom() { SetTargetEyeHeight(CrouchedEyeHeight); GetCharacterMovement()->MaxWalkSpeed = CrouchSpeed; bIsCrouched = true; CrouchTimeline.Play(); //float CurrentCamHeight = GetCurrentEyeHeight(); //GetCapsuleComponent()->SetCapsuleHalfHeight(GetCharacterMovement()->CrouchedHalfHeight); // CameraComponent->SetRelativeLocation( // FVector(0, 0, GetFootOffset()) + // FVector(0, 0, CurrentCamHeight)); } void AExoPlayerCharacter::TryUnCrouchCustom() { SetTargetEyeHeight(StandingEyeHeight); GetCharacterMovement()->MaxWalkSpeed = WalkSpeed; bIsCrouched = false; CrouchTimeline.Reverse(); //float CurrentCamHeight = GetCurrentEyeHeight(); //GetCapsuleComponent()->SetCapsuleHalfHeight(StandingHalfHeight); //CameraComponent->SetRelativeLocation( // FVector(0, 0, GetFootOffset()) + // FVector(0, 0, CurrentCamHeight)); } void AExoPlayerCharacter::AddHealthPoints(float addValue) { CurrentHealth += addValue; if (CurrentHealth > MaxHealth) CurrentHealth = MaxHealth; if (PlayerHud) PlayerHud->SetHp(CurrentHealth,MaxHealth); } float AExoPlayerCharacter::GetStandingEyeHeight(const bool bCapsuleRelative) const { return bCapsuleRelative ? StandingEyeHeight - GetCapsuleComponent()->GetScaledCapsuleHalfHeight() : StandingEyeHeight; } float AExoPlayerCharacter::GetCrouchingEyeHeight(const bool bCapsuleRelative) const { return bCapsuleRelative ? CrouchedEyeHeight - GetCapsuleComponent()->GetScaledCapsuleHalfHeight() : CrouchedEyeHeight; } bool AExoPlayerCharacter::IsCrouching() const { return bIsCrouched; } void AExoPlayerCharacter::SetEyePositionOffsetTarget(const FVector LocationOffset) { //LocationOffset.Z = FMath::Clamp(LocationOffset.Z, CoverEyeHeight, StandingEyeHeight); UE_LOG(LogTemp, Log, TEXT("Eye offset set to: %s"), *LocationOffset.ToString()); TargetEyeLocationOffset = LocationOffset; } void AExoPlayerCharacter::SetEyeRoll(float RollValue) { TargetEyeRoll = RollValue; } FVector AExoPlayerCharacter::GetPlayerLocationAtFeet() const { FVector ReturnVector = GetActorLocation(); ReturnVector.Z -= GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); return ReturnVector; } void AExoPlayerCharacter::SetTargetEyeHeight(float NewEyeHeight, const bool bCapsuleRelative) { if (bCapsuleRelative) { NewEyeHeight += GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); } UE_LOG(LogTemp, Log, TEXT("Target eye height set to: %f"), NewEyeHeight); TargetEyeHeight = FMath::Clamp(NewEyeHeight, CrouchedEyeHeight + LowEyeHeightOffset, StandingEyeHeight ); } float AExoPlayerCharacter::GetCurrentEyeHeight(const bool bCapsuleRelative) const { float ReturnValue = CameraComponent->GetRelativeLocation().Z; if (!bCapsuleRelative) { ReturnValue += GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); } return ReturnValue; }