feat: Character camera and simple cover system
This commit is contained in:
parent
848f500933
commit
8c9bc0f44e
|
|
@ -32,5 +32,10 @@
|
||||||
"Name": "MDL",
|
"Name": "MDL",
|
||||||
"Enabled": false
|
"Enabled": false
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"TargetPlatforms": [
|
||||||
|
"Linux",
|
||||||
|
"LinuxArm64",
|
||||||
|
"Windows"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "GameFramework/CharacterMovementComponent.h"
|
#include "GameFramework/CharacterMovementComponent.h"
|
||||||
#include "Items/AmmoBoxBase.h"
|
#include "Items/AmmoBoxBase.h"
|
||||||
#include "Items/HealthBoxBase.h"
|
#include "Items/HealthBoxBase.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
#include "Player/InteractionComponent.h"
|
#include "Player/InteractionComponent.h"
|
||||||
#include "Widget/WBP_PlayerUI.h"
|
#include "Widget/WBP_PlayerUI.h"
|
||||||
|
|
||||||
|
|
@ -26,9 +27,15 @@ AExoPlayerCharacter::AExoPlayerCharacter()
|
||||||
Weapon->CastShadow = false;
|
Weapon->CastShadow = false;
|
||||||
Weapon->SetRelativeLocation(FVector(-50.f, 0.f, -90.f));
|
Weapon->SetRelativeLocation(FVector(-50.f, 0.f, -90.f));
|
||||||
|
|
||||||
bUseControllerRotationPitch = false;
|
//bUseControllerRotationPitch = false;
|
||||||
bUseControllerRotationYaw = true;
|
//bUseControllerRotationYaw = true;
|
||||||
bUseControllerRotationRoll = false;
|
//bUseControllerRotationRoll = false;
|
||||||
|
|
||||||
|
// Setup camera component
|
||||||
|
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
|
||||||
|
CameraComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
|
||||||
|
CameraComponent->bUsePawnControlRotation = true;
|
||||||
|
CameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, BaseEyeHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AExoPlayerCharacter::BeginPlay()
|
void AExoPlayerCharacter::BeginPlay()
|
||||||
|
|
@ -36,7 +43,8 @@ void AExoPlayerCharacter::BeginPlay()
|
||||||
Super::BeginPlay();
|
Super::BeginPlay();
|
||||||
|
|
||||||
GetCapsuleComponent()->OnComponentBeginOverlap.AddDynamic(this, &AExoPlayerCharacter::OnActorBeginOverlap);
|
GetCapsuleComponent()->OnComponentBeginOverlap.AddDynamic(this, &AExoPlayerCharacter::OnActorBeginOverlap);
|
||||||
|
//UGameplayStatics::GetPlayerCameraManager(GetWorld(), 0)->SetViewTarget(this);
|
||||||
|
StandingEyeHeight = CameraComponent->GetRelativeLocation().Z;
|
||||||
|
|
||||||
|
|
||||||
PlayerHud = CreateWidget<UWBP_PlayerUI>(GetWorld(),PlayerHudClass);
|
PlayerHud = CreateWidget<UWBP_PlayerUI>(GetWorld(),PlayerHudClass);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "Characters/ExoPlayerCharacter.h"
|
#include "Characters/ExoPlayerCharacter.h"
|
||||||
#include "GameFramework/Character.h"
|
#include "GameFramework/Character.h"
|
||||||
#include "GameFramework/CharacterMovementComponent.h"
|
#include "GameFramework/CharacterMovementComponent.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
AExoPlayerController::AExoPlayerController()
|
AExoPlayerController::AExoPlayerController()
|
||||||
{
|
{
|
||||||
|
|
@ -28,17 +29,34 @@ void AExoPlayerController::BeginPlay()
|
||||||
Subsystem->AddMappingContext(InputContext, 0);
|
Subsystem->AddMappingContext(InputContext, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
InteractionComponent = PlayerCharacter->FindComponentByClass<UInteractionComponent>();
|
//InteractionComponent = PlayerCharacter->FindComponentByClass<UInteractionComponent>();
|
||||||
ShootingComponent = PlayerCharacter->FindComponentByClass<UShootingComponent>();
|
//ShootingComponent = PlayerCharacter->FindComponentByClass<UShootingComponent>();
|
||||||
|
InteractionComponent = PlayerCharacter->InteractionComponent;
|
||||||
|
ShootingComponent = PlayerCharacter->ShootingComponent;
|
||||||
|
|
||||||
// Ustawianie w komponencie poruszania pr<70>dko<6B>ci zapisanej w characterze
|
// Ustawianie w komponencie poruszania pr<70>dko<6B>ci zapisanej w characterze
|
||||||
PlayerCharacter->GetCharacterMovement()->MaxWalkSpeed = PlayerCharacter->WalkSpeed;
|
PlayerCharacter->GetCharacterMovement()->MaxWalkSpeed = PlayerCharacter->WalkSpeed;
|
||||||
|
|
||||||
|
// Oblicz prawidłową maksymalną wysokość na którą można wychylić się z nad osłony
|
||||||
|
|
||||||
|
UE_LOG(LogTemp, Display, TEXT("MaxCoverAimHeight: %f"), MaxCoverAimHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AExoPlayerController::PlayerTick(float DeltaTime)
|
void AExoPlayerController::PlayerTick(float DeltaTime)
|
||||||
{
|
{
|
||||||
Super::PlayerTick(DeltaTime);
|
Super::PlayerTick(DeltaTime);
|
||||||
|
|
||||||
|
// TESTING
|
||||||
|
if (bIsInCover)
|
||||||
|
{
|
||||||
|
AdjustCameraWhileInCover();
|
||||||
|
}
|
||||||
|
UpdateCoverStandHeight(DeltaTime);
|
||||||
|
|
||||||
|
if (bShowCoverSystemDebug)
|
||||||
|
{
|
||||||
|
GEngine->AddOnScreenDebugMessage(2, -1, FColor::Red, FString::Printf(TEXT("In cover: %s"), bIsInCover ? "true" : "false"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AExoPlayerController::SetupInputComponent()
|
void AExoPlayerController::SetupInputComponent()
|
||||||
|
|
@ -141,11 +159,36 @@ void AExoPlayerController::PlayerStartCrouch()
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerCharacter->Crouch();
|
PlayerCharacter->Crouch();
|
||||||
|
PlayerCharacter->CameraComponent->SetRelativeLocation(FVector(
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
PlayerCharacter->CrouchedEyeHeight)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Start checking for cover
|
||||||
|
bIsInCover = CheckForCover();
|
||||||
|
GetWorld()->GetTimerManager().SetTimer(
|
||||||
|
CoverCheckTimer,
|
||||||
|
this,
|
||||||
|
&AExoPlayerController::OnCoverTimer,
|
||||||
|
CoverCheckRate,
|
||||||
|
true
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AExoPlayerController::PlayerStopCrouch()
|
void AExoPlayerController::PlayerStopCrouch()
|
||||||
{
|
{
|
||||||
PlayerCharacter->UnCrouch();
|
PlayerCharacter->UnCrouch();
|
||||||
|
PlayerCharacter->CameraComponent->SetRelativeLocation(FVector(
|
||||||
|
0.0f,
|
||||||
|
0.0f,
|
||||||
|
PlayerCharacter->BaseEyeHeight)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Stop checking for cover
|
||||||
|
GetWorld()->GetTimerManager().ClearTimer(CoverCheckTimer);
|
||||||
|
bIsInCover = false;
|
||||||
|
TargetCoverStandAlpha = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AExoPlayerController::ResetSlide()
|
void AExoPlayerController::ResetSlide()
|
||||||
|
|
@ -224,3 +267,258 @@ void AExoPlayerController::PlayerReload()
|
||||||
{
|
{
|
||||||
ShootingComponent->Reload();
|
ShootingComponent->Reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
TraceStart.Z -= PlayerCharacter->GetCapsuleComponent()->GetScaledCapsuleHalfHeight() - CoverObstacleMinHeight;
|
||||||
|
FCollisionQueryParams QueryParams;
|
||||||
|
QueryParams.AddIgnoredActor(PlayerCharacter);
|
||||||
|
|
||||||
|
TArray<FHitResult> ValidHits;
|
||||||
|
for (int i = 0; i <= 8; i++)
|
||||||
|
{
|
||||||
|
// Trace for possible cover at set distance
|
||||||
|
FHitResult Hit;
|
||||||
|
FVector TraceEnd = TraceStart + (TraceDirection * MaxDistanceFromCover);
|
||||||
|
GetWorld()->LineTraceSingleByChannel(
|
||||||
|
Hit,
|
||||||
|
TraceStart,
|
||||||
|
TraceEnd,
|
||||||
|
CoverTraceChannel,
|
||||||
|
QueryParams
|
||||||
|
);
|
||||||
|
|
||||||
|
if (bShowCoverSystemDebug)
|
||||||
|
{
|
||||||
|
// DEBUG
|
||||||
|
DrawDebugLine(GetWorld(), TraceStart,TraceEnd,
|
||||||
|
Hit.bBlockingHit ? FColor::Blue : FColor::Red,
|
||||||
|
false, 5.0f, 0, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Hit.bBlockingHit == true) {
|
||||||
|
// Check if this particular hit isn't against a wall (>CoverMaxHeight)
|
||||||
|
|
||||||
|
FHitResult SphereHit;
|
||||||
|
FVector SpherePosition = Hit.ImpactPoint +
|
||||||
|
FVector(
|
||||||
|
0.0f, 0.0f,
|
||||||
|
CoverObstacleMaxHeight + CoverAimWindowRadius - CoverObstacleMinHeight);
|
||||||
|
|
||||||
|
GetWorld()->SweepSingleByChannel(
|
||||||
|
SphereHit,
|
||||||
|
SpherePosition,
|
||||||
|
SpherePosition,
|
||||||
|
FQuat::Identity,
|
||||||
|
CoverTraceChannel,
|
||||||
|
FCollisionShape::MakeSphere(CoverAimWindowRadius),
|
||||||
|
QueryParams);
|
||||||
|
|
||||||
|
if (bShowCoverSystemDebug)
|
||||||
|
{
|
||||||
|
DrawDebugSphere(GetWorld(), SphereHit.TraceStart, CoverAimWindowRadius, 8,
|
||||||
|
Hit.bBlockingHit ? FColor::Blue : FColor::Red,
|
||||||
|
false, 5.0f, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SphereHit.bBlockingHit == false)
|
||||||
|
{
|
||||||
|
ValidHits.Add(Hit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Rotate trace to search in another direction next time
|
||||||
|
TraceDirection = TraceDirection.RotateAngleAxis(45, FVector(0, 0, 1));
|
||||||
|
//UE_LOG(LogTemp, Display, TEXT("Check Cover %d"), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ValidHits.Num() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AExoPlayerController::AdjustCameraWhileInCover()
|
||||||
|
{
|
||||||
|
if (!bIsInCover)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MaxCoverAimHeight = PlayerCharacter->StandingEyeHeight * CoverAimStandFactor;
|
||||||
|
|
||||||
|
//FVector StartOffset = GetCharacter()->GetActorForwardVector() * 20.0f;
|
||||||
|
FVector ObstacleTraceStart = GetCharacter()->GetActorLocation();
|
||||||
|
ObstacleTraceStart.Z += GetCharacter()->CrouchedEyeHeight;
|
||||||
|
FVector ObstacleTraceEnd =
|
||||||
|
ObstacleTraceStart + PlayerCameraManager->GetCameraRotation().Vector() * CoverAimFreeDistance;
|
||||||
|
FCollisionQueryParams QueryParams;
|
||||||
|
QueryParams.AddIgnoredActor(PlayerCharacter);
|
||||||
|
TEnumAsByte<ECollisionChannel> ObstacleTraceChannel = ECC_WorldStatic;
|
||||||
|
|
||||||
|
FHitResult Hit;
|
||||||
|
bool bFreeSpace = false;
|
||||||
|
|
||||||
|
// Trace until no hit is found (free space to aim)
|
||||||
|
for (int i = 0; i < MaxCoverAimHeight; i += 2*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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bFreeSpace)
|
||||||
|
{
|
||||||
|
TargetCoverStandAlpha = FMath::GetMappedRangeValueClamped(
|
||||||
|
UE::Math::TVector2<float>(GetCharacter()->CrouchedEyeHeight, GetCharacter()->CrouchedEyeHeight + MaxCoverAimHeight),
|
||||||
|
UE::Math::TVector2(0.0f, 1.0f),
|
||||||
|
Hit.TraceStart.Z
|
||||||
|
);
|
||||||
|
if (bShowCoverSystemDebug)
|
||||||
|
{
|
||||||
|
DrawDebugLine(GetWorld(), Hit.TraceStart, Hit.TraceEnd, FColor::Red);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// IDEA FOR A MORE COMPLEX SYSTEM IN THE FUTURE:
|
||||||
|
//vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
||||||
|
// To not introduce accidental flickering and optimize it a bit, all of this should run
|
||||||
|
// ONLY on cover update
|
||||||
|
|
||||||
|
// FVector CrouchedEyeWorldPosition = PlayerCharacter->GetActorLocation();
|
||||||
|
// CrouchedEyeWorldPosition.Z += PlayerCharacter->CrouchedEyeHeight;
|
||||||
|
// FVector CoverCeiling = CrouchedEyeWorldPosition + MaxCoverAimHeight;
|
||||||
|
// float PlayerCapsuleRadius = PlayerCharacter->GetCapsuleComponent()->GetScaledCapsuleHalfHeight();
|
||||||
|
// TEnumAsByte<ECollisionChannel> ObstacleTraceChannel = ECC_WorldStatic;
|
||||||
|
// FCollisionQueryParams QueryParams;
|
||||||
|
// QueryParams.AddIgnoredActor(PlayerCharacter);
|
||||||
|
//
|
||||||
|
// // Shoot ray up at maximum cover length to determine how high the player can "stand up"
|
||||||
|
// FHitResult WallTopHit;
|
||||||
|
// GetWorld()->SweepSingleByChannel(
|
||||||
|
// WallTopHit,
|
||||||
|
// CrouchedEyeWorldPosition,
|
||||||
|
// CoverCeiling,
|
||||||
|
// FQuat::Identity,
|
||||||
|
// ObstacleTraceChannel,
|
||||||
|
// FCollisionShape::MakeSphere(PlayerCapsuleRadius),
|
||||||
|
// QueryParams
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// FVector CeilingWorldLocation;
|
||||||
|
// if (WallTopHit.bBlockingHit == true)
|
||||||
|
// {
|
||||||
|
// CeilingWorldLocation = WallTopHit.Location;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// CeilingWorldLocation = WallTopHit.TraceEnd;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // From hit location (or if no hit - from end position) shoot ray towards camera's forward
|
||||||
|
// // vector at minimum cover length
|
||||||
|
//
|
||||||
|
// constexpr float WallFinderDistance = 75.0f;
|
||||||
|
// FVector WallFinderDirection = PlayerCharacter->GetActorForwardVector();
|
||||||
|
// WallFinderDirection.Z = 0.0f; // Not needed if the player always stays upright
|
||||||
|
//
|
||||||
|
// GetWorld()->LineTraceSingleByChannel(
|
||||||
|
// WallTopHit,
|
||||||
|
// CeilingWorldLocation,
|
||||||
|
// CeilingWorldLocation + (WallFinderDirection * WallFinderDistance),
|
||||||
|
// ObstacleTraceChannel,
|
||||||
|
// QueryParams
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// // regardless of the hit result shoot multi-ray downwards from end location
|
||||||
|
// // with maximum cover length
|
||||||
|
//
|
||||||
|
// FVector WallTopTraceStart = WallTopHit.bBlockingHit ? WallTopHit.Location : WallTopHit.TraceEnd;
|
||||||
|
// TArray<FHitResult> ValidHitsCandidateArray;
|
||||||
|
//
|
||||||
|
// GetWorld()->LineTraceMultiByChannel(
|
||||||
|
// ValidHitsCandidateArray,
|
||||||
|
// WallTopTraceStart,
|
||||||
|
// WallTopTraceStart + (FVector(0.0f, 0.0f, 0.0f) * MaxCoverAimHeight),
|
||||||
|
// ObstacleTraceChannel,
|
||||||
|
// QueryParams
|
||||||
|
// );
|
||||||
|
|
||||||
|
// On every ray hit trace an in-place sphere to determine if the aiming spot is valid
|
||||||
|
|
||||||
|
// All valid aiming spots are collected and the lowest (smallest Z) is chosen
|
||||||
|
|
||||||
|
// Sphere trace from camera forward a certain distance to regulate camera position while
|
||||||
|
// aiming up and down // TODO: elaborate
|
||||||
|
}
|
||||||
|
|
||||||
|
void AExoPlayerController::UpdateCoverStandHeight(float DeltaTime)
|
||||||
|
{
|
||||||
|
// if (FMath::IsNearlyEqual(CoverStandAlpha, TargetCoverStandAlpha, 0.01f))
|
||||||
|
// {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
CoverStandAlpha = FMath::Lerp(CoverStandAlpha, TargetCoverStandAlpha, DeltaTime * 5.0f);
|
||||||
|
//CoverStandAlpha = TargetCoverStandAlpha;
|
||||||
|
|
||||||
|
// BANDAID SOLUTION
|
||||||
|
const float NewZ = FMath::Lerp(
|
||||||
|
PlayerCharacter->CrouchedEyeHeight,
|
||||||
|
PlayerCharacter->StandingEyeHeight,
|
||||||
|
CoverStandAlpha
|
||||||
|
);
|
||||||
|
|
||||||
|
PlayerCharacter->CameraComponent->SetRelativeLocation(
|
||||||
|
FVector(0.0f, 0.0f, NewZ)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (bShowCoverSystemDebug && GEngine)
|
||||||
|
{
|
||||||
|
GEngine->AddOnScreenDebugMessage(1, -1, FColor::Red, FString::Printf(TEXT("Current cover stand alpha: %f"), CoverStandAlpha));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AExoPlayerController::OnCoverTimer()
|
||||||
|
{
|
||||||
|
bIsInCover = CheckForCover();
|
||||||
|
if (bIsInCover == false)
|
||||||
|
{
|
||||||
|
TargetCoverStandAlpha = 0.0f;
|
||||||
|
UpdateCoverStandHeight(GetWorld()->GetDeltaSeconds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AExoPlayerController::DebugCoverSystem(bool show)
|
||||||
|
{
|
||||||
|
bShowCoverSystemDebug = show;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -104,6 +104,11 @@ private:
|
||||||
void ReloadCompleted();
|
void ReloadCompleted();
|
||||||
AActor* ExecuteLineTrace(float LineRange);
|
AActor* ExecuteLineTrace(float LineRange);
|
||||||
|
|
||||||
|
// Cover logic - ToQly
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
FTimerHandle ShootCooldownTimer;
|
FTimerHandle ShootCooldownTimer;
|
||||||
FTimerHandle ReloadTimer;
|
FTimerHandle ReloadTimer;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
|
#include "Camera/CameraComponent.h"
|
||||||
#include "Characters/ExoCharacterBase.h"
|
#include "Characters/ExoCharacterBase.h"
|
||||||
#include "Components/CapsuleComponent.h"
|
#include "Components/CapsuleComponent.h"
|
||||||
#include "ExoPlayerCharacter.generated.h"
|
#include "ExoPlayerCharacter.generated.h"
|
||||||
|
|
@ -28,6 +29,12 @@ public:
|
||||||
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
|
||||||
TObjectPtr<UShootingComponent> ShootingComponent;
|
TObjectPtr<UShootingComponent> ShootingComponent;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Camera")
|
||||||
|
TObjectPtr<UCameraComponent> CameraComponent;
|
||||||
|
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="Camera")
|
||||||
|
float StandingEyeHeight;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, Category = "Dodge Properties")
|
UPROPERTY(EditAnywhere, Category = "Dodge Properties")
|
||||||
float DodgeForce = 5000.f;
|
float DodgeForce = 5000.f;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,24 @@ protected:
|
||||||
UFUNCTION(BlueprintCallable, Category = "Input")
|
UFUNCTION(BlueprintCallable, Category = "Input")
|
||||||
void PlayerReload(); // R
|
void PlayerReload(); // R
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Cover System")
|
||||||
|
bool CheckForCover();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Cover System")
|
||||||
|
void AdjustCameraWhileInCover();
|
||||||
|
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Cover System")
|
||||||
|
void UpdateCoverStandHeight(float DeltaTime);
|
||||||
|
|
||||||
|
void OnCoverTimer();
|
||||||
|
|
||||||
|
float MapAlphaToCoverStandHeight(float Alpha);
|
||||||
|
|
||||||
|
// DEBUG
|
||||||
|
UFUNCTION(Exec, Category = "Cover System")
|
||||||
|
void DebugCoverSystem(bool show);
|
||||||
|
bool bShowCoverSystemDebug = false;
|
||||||
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, Category = "Input")
|
UPROPERTY(EditAnywhere, Category = "Input")
|
||||||
TObjectPtr<UInputMappingContext> InputContext;
|
TObjectPtr<UInputMappingContext> InputContext;
|
||||||
|
|
@ -159,8 +177,62 @@ protected:
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Character")
|
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Character")
|
||||||
TObjectPtr<AExoPlayerCharacter> PlayerCharacter;
|
TObjectPtr<AExoPlayerCharacter> PlayerCharacter;
|
||||||
|
|
||||||
|
// Czy postać gracza jest obecnie schowana za osłoną
|
||||||
|
UPROPERTY(EditAnywhere, Category = "Cover System")
|
||||||
|
bool bIsInCover = false;
|
||||||
|
|
||||||
|
/** 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;
|
||||||
|
|
||||||
|
// Dystans na którym postać jest w stanie odnaleźć osłonę
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cover System")
|
||||||
|
float MaxDistanceFromCover = 50.0f;
|
||||||
|
|
||||||
|
// Minimalna wysokość przeszkody którą można określić osłoną
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cover System")
|
||||||
|
float CoverObstacleMinHeight = 75.0f;
|
||||||
|
|
||||||
|
// Maksymalna wysokość przeszkody którą można określić osłoną
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cover System")
|
||||||
|
float CoverObstacleMaxHeight = 125.0f;
|
||||||
|
|
||||||
|
// Promień wolnej przestrzeni przez którą można się wychylić
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cover System")
|
||||||
|
float CoverAimWindowRadius = 2.0f;
|
||||||
|
|
||||||
|
// Dystans od kamery po wychyleniu który musi być wolny by dało się wychylić
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cover System")
|
||||||
|
float CoverAimFreeDistance = 150.0f;
|
||||||
|
|
||||||
|
/** Określa na jaki procent "Stania" postać może się podnieść podczas celowania
|
||||||
|
* zza osłony. 0 -> Nie podniesie się wogóle (jakby wychylanie się było wyłączone)
|
||||||
|
* 1 -> Postać jest w stanie się podnieść do pełnej wysokości, tak jakby normalnie stała
|
||||||
|
**/
|
||||||
|
UPROPERTY(EditAnywhere,
|
||||||
|
meta = (ClampMin = "0.0", ClampMax = "1.0",
|
||||||
|
UIMin = "0.0",
|
||||||
|
UIMax = "1.0") ,
|
||||||
|
BlueprintReadWrite, Category = "Cover System")
|
||||||
|
float CoverAimStandFactor = 0.9f;
|
||||||
|
|
||||||
|
// Trace Channel po którym szukać geometrii potencjalnych osłon
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cover System")
|
||||||
|
TEnumAsByte<ECollisionChannel> CoverTraceChannel = ECC_WorldStatic;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UInteractionComponent* InteractionComponent;
|
UInteractionComponent* InteractionComponent;
|
||||||
|
|
||||||
UShootingComponent* ShootingComponent;
|
UShootingComponent* ShootingComponent;
|
||||||
|
|
||||||
|
float CoverStandAlpha = 0.0f;
|
||||||
|
FTimerHandle CoverCheckTimer;
|
||||||
|
float MaxCoverAimHeight;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user