// 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 "Kismet/GameplayStatics.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; CapsuleBottom = CreateDefaultSubobject(TEXT("CapsuleBottom")); CapsuleBottom->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform); CapsuleBottom->SetRelativeLocation(FVector(0, 0, -GetCapsuleComponent()->GetScaledCapsuleHalfHeight())); // 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, FromFeet(TargetEyeHeight))); GetCapsuleComponent()->OnComponentBeginOverlap.AddDynamic(this, &AExoPlayerCharacter::OnActorBeginOverlap); 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->AddDebuf(NULL,0.25f*i); } } } void AExoPlayerCharacter::Tick(float DeltaTime) { Super::Tick(DeltaTime); UpdateCameraHeight(DeltaTime); ApplyCameraOffsets(DeltaTime); } float AExoPlayerCharacter::GetFootOffset() { return -GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); } void AExoPlayerCharacter::UpdateCameraHeight(float DeltaTime) { if (FMath::IsNearlyEqual(GetCurrentEyeHeight(), TargetEyeHeight, 0.01f)) { return; } const float NewHeight = FMath::Lerp(GetCurrentEyeHeight(), TargetEyeHeight, DeltaTime*5); const FVector CamRelXY = CameraComponent->GetRelativeLocation(); EyeHeight = GetFootOffset() + NewHeight; CameraComponent->SetRelativeLocation(FVector(CamRelXY.X, CamRelXY.Y,EyeHeight)); } void AExoPlayerCharacter::ApplyCameraOffsets(float DeltaTime) { bool HasChanged = false; if (!FVector::PointsAreNear(EyeLocationOffset, TargetEyeLocationOffset, 0.01f)) { // Smoothly offset view EyeLocationOffset = FMath::Lerp(EyeLocationOffset, TargetEyeLocationOffset, 5*DeltaTime); HasChanged = true; } if (!FMath::IsNearlyEqual(EyeRoll, TargetEyeRoll, 0.01f)) { // Smoothly rotate view EyeRoll = FMath::Lerp(EyeRoll, TargetEyeRoll, DeltaTime*5); HasChanged = true; } if (!HasChanged) { // Do not calculate anything if nothing changed return; } // Update actual camera position const FVector FinalOffset = FVector(EyeLocationOffset.X, EyeLocationOffset.Y, EyeLocationOffset.Z + TargetEyeHeight + GetFootOffset()); CameraComponent->SetRelativeLocation(FinalOffset); // 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; 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; 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::ToFeet(float value) { return value + GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); } float AExoPlayerCharacter::FromFeet(float value) { return value - GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); } /*float AExoPlayerCharacter::GetCurrentEyeHeightBase(const bool bCapsuleRelative) { if (bIsCrouched) { return GetCrouchingEyeHeight(bCapsuleRelative); } return GetStandingEyeHeight(bCapsuleRelative); }*/ 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) { float ReturnValue = CameraComponent->GetRelativeLocation().Z; if (!bCapsuleRelative) { ReturnValue += GetCapsuleComponent()->GetScaledCapsuleHalfHeight(); } return ReturnValue; }