Add Camera Shake when player is damaged

This commit is contained in:
baz 2025-04-23 23:27:05 +01:00
parent c9c128ba44
commit 9ddc4c9ace
4 changed files with 61 additions and 8 deletions

BIN
Content/Player/BP_PlayerCharacter.uasset (Stored with Git LFS)

Binary file not shown.

BIN
Content/Player/C_Shake.uasset (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -29,6 +29,16 @@ APlayerCharacter::APlayerCharacter()
HealthBarWidgetComponent->SetTwoSided(true); HealthBarWidgetComponent->SetTwoSided(true);
HealthBarWidgetComponent->SetBackgroundColor(FLinearColor(1, 1, 1, 0)); HealthBarWidgetComponent->SetBackgroundColor(FLinearColor(1, 1, 1, 0));
HealthBarWidgetComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision); HealthBarWidgetComponent->SetCollisionEnabled(ECollisionEnabled::NoCollision);
CameraShakeTimelineComponent = CreateDefaultSubobject<UTimelineComponent>(TEXT("Camera Shake Timeline Component"));
CameraShakeTimelineComponent->SetDirectionPropertyName(FName("TimelineDirection"));
CameraShakeTimelineComponent->SetLooping(false);
CameraShakeTimelineComponent->SetTimelineLength(0.5f);
CameraShakeTimelineComponent->SetTimelineLengthMode(TL_TimelineLength);
CameraShakeTimelineComponent->SetPlaybackPosition(0.0f, false);
onTimelineCallback.BindUFunction(this, FName(TEXT("CameraShakeTimelineCallback")));
onTimelineFinishedCallback.BindUFunction(this, FName(TEXT("CameraShakeTimelineFinishedCallback")));
} }
void APlayerCharacter::BeginPlay() void APlayerCharacter::BeginPlay()
@ -37,6 +47,14 @@ void APlayerCharacter::BeginPlay()
GetHealthComponent()->OnDamaged.AddDynamic(this, &APlayerCharacter::OnDamaged); GetHealthComponent()->OnDamaged.AddDynamic(this, &APlayerCharacter::OnDamaged);
GetHealthComponent()->OnDeath.AddDynamic(this, &APlayerCharacter::OnDeath); GetHealthComponent()->OnDeath.AddDynamic(this, &APlayerCharacter::OnDeath);
if (CameraShakeCurve != nullptr)
{
CameraShakeTimelineComponent->AddInterpFloat(CameraShakeCurve, onTimelineCallback);
CameraShakeTimelineComponent->SetTimelineFinishedFunc(onTimelineFinishedCallback);
}
PlayerCameraManager = GetWorld()->GetFirstPlayerController()->PlayerCameraManager;
} }
void APlayerCharacter::Tick(float DeltaTime) void APlayerCharacter::Tick(float DeltaTime)
@ -78,11 +96,7 @@ void APlayerCharacter::OnDamaged(FDamageInfo damageInfo)
UGameplayStatics::PlaySoundAtLocation(GetWorld(), OnDamagedSound, GetActorLocation()); UGameplayStatics::PlaySoundAtLocation(GetWorld(), OnDamagedSound, GetActorLocation());
} }
APlayerController* playerController = UGameplayStatics::GetPlayerController(this, 0); CameraShakeTimelineComponent->PlayFromStart();
if (playerController && CameraShake)
{
playerController->ClientStartCameraShake(CameraShake);
}
} }
void APlayerCharacter::OnDeath(FDamageInfo damageInfo) void APlayerCharacter::OnDeath(FDamageInfo damageInfo)
@ -94,3 +108,17 @@ void APlayerCharacter::OnDeath(FDamageInfo damageInfo)
// TODO: End the game // TODO: End the game
} }
void APlayerCharacter::CameraShakeTimelineCallback(float val)
{
auto PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);
auto cameraActor = PlayerController->GetViewTarget();
cameraActor->SetActorLocation(FVector(FMath::RandRange(0.0f, CameraShakeStrength) * val, FMath::RandRange(0.0f, CameraShakeStrength) * val, 0.0f));
}
void APlayerCharacter::CameraShakeTimelineFinishedCallback()
{
auto PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);
auto cameraActor = PlayerController->GetViewTarget();
cameraActor->SetActorLocation(FVector::ZeroVector);
}

View File

@ -4,8 +4,10 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "VampireCharacter.h" #include "VampireCharacter.h"
#include "Components/TimelineComponent.h"
#include "PlayerCharacter.generated.h" #include "PlayerCharacter.generated.h"
struct FDamageInfo;
struct FInputActionInstance; struct FInputActionInstance;
class UWidgetComponent; class UWidgetComponent;
class UWeaponInventoryComponent; class UWeaponInventoryComponent;
@ -32,11 +34,25 @@ public:
UPROPERTY(EditAnywhere) UPROPERTY(EditAnywhere)
UWidgetComponent* HealthBarWidgetComponent; UWidgetComponent* HealthBarWidgetComponent;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
TObjectPtr<UTimelineComponent> CameraShakeTimelineComponent = nullptr;
UPROPERTY(EditAnywhere) UPROPERTY(EditAnywhere)
TSubclassOf<UCameraShakeBase> CameraShake; TObjectPtr<UCurveFloat> CameraShakeCurve;
UPROPERTY(EditAnywhere)
float CameraShakeStrength = 100.0f;
private:
TObjectPtr<APlayerCameraManager> PlayerCameraManager = nullptr;
APlayerCharacter(); APlayerCharacter();
private:
FOnTimelineFloat onTimelineCallback;
FOnTimelineEventStatic onTimelineFinishedCallback;
protected: protected:
virtual void BeginPlay() override; virtual void BeginPlay() override;
@ -53,4 +69,10 @@ private:
UFUNCTION() UFUNCTION()
virtual void OnDeath(FDamageInfo damageInfo); virtual void OnDeath(FDamageInfo damageInfo);
UFUNCTION()
void CameraShakeTimelineCallback(float val);
UFUNCTION()
void CameraShakeTimelineFinishedCallback();
}; };