ExoWest/Source/Exo/Private/Characters/ExoPlayerCharacter.cpp

289 lines
8.2 KiB
C++
Raw Normal View History

// 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"
2025-05-08 17:46:09 +02:00
#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<USceneComponent>(TEXT("CapsuleBottom"));
CapsuleBottom->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
CapsuleBottom->SetRelativeLocation(FVector(0, 0, -GetCapsuleComponent()->GetScaledCapsuleHalfHeight()));
// Create camera component
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
CameraComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
CameraComponent->bUsePawnControlRotation = true;
GetCharacterMovement()->bSnapToPlaneAtStart = true;
InteractionComponent = CreateDefaultSubobject<UInteractionComponent>(TEXT("Interaction Component"));
ShootingComponent = CreateDefaultSubobject<UShootingComponent>(TEXT("Shooting Component"));
Weapon = CreateDefaultSubobject<USkeletalMeshComponent>("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);
2025-05-08 17:46:09 +02:00
PlayerHud = CreateWidget<UWBP_PlayerUI>(GetWorld(),PlayerHudClass);
if (PlayerHud)
{
2025-05-08 17:46:09 +02:00
PlayerHud->AddToViewport();
PlayerHud->AddToPlayerScreen();
if (PlayerHud)
{
2025-05-08 17:46:09 +02:00
PlayerHud->SetHp(CurrentHealth,MaxHealth);
2025-05-22 17:21:59 +02:00
PlayerHud->SetAmmoNumber(10);
PlayerHud->SetAmmoType(EAmmoType::Revolver);
for (int i=0;i<4;i++)
PlayerHud->AddDebuf(NULL,0.25f*i);
2025-05-08 17:46:09 +02:00
}
}
}
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);
2025-06-01 17:55:38 +02:00
// 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<AHealthBoxBase>(OtherActor);
if (HealthBox)
{
AddHealthPoints(HealthBox->HealthValue);
HealthBox->Destroy();
UE_LOG(LogTemp, Warning, TEXT("Zebrano apteczkę"));
}
}
else if (OtherActor->IsA(AAmmoBoxBase::StaticClass()))
{
AAmmoBoxBase* AmmoBox = Cast<AAmmoBoxBase>(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;
2025-06-01 17:55:38 +02:00
bIsCrouched = true;
float CurrentCamHeight = GetCurrentEyeHeight();
2025-06-01 17:55:38 +02:00
GetCapsuleComponent()->SetCapsuleHalfHeight(GetCharacterMovement()->CrouchedHalfHeight);
CameraComponent->SetRelativeLocation(
FVector(0, 0, GetFootOffset()) +
FVector(0, 0, CurrentCamHeight));
}
2025-06-01 17:55:38 +02:00
void AExoPlayerCharacter::TryUnCrouchCustom()
{
SetTargetEyeHeight(StandingEyeHeight);
GetCharacterMovement()->MaxWalkSpeed = WalkSpeed;
float CurrentCamHeight = GetCurrentEyeHeight();
2025-06-01 17:55:38 +02:00
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;
2025-05-08 17:46:09 +02:00
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;
}
2025-06-01 17:55:38 +02:00
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;
}