feat: add recoil, fire rate and reloading

Added recoil force while shooting
Added fire rate system
Implement reloading
This commit is contained in:
Kubson96 2025-02-22 01:28:07 +01:00
parent 9e7fab3544
commit 0f2fac10bd
4 changed files with 75 additions and 11 deletions

View File

@ -19,36 +19,67 @@ void UShootingComponent::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
// ... PlayerCharacter = Cast<AExoPlayerCharacter>(GetOwner());
} }
void UShootingComponent::Shoot() void UShootingComponent::Shoot()
{ {
AActor* Owner = GetOwner(); if (CurrentAmmo == 0 || bIsReloading || !bCanShoot) return;
FVector LineStart = Owner->GetActorLocation(); bCanShoot = false;
FVector ForwardVector = Owner->GetActorForwardVector(); CurrentAmmo--;
FVector LineStart = PlayerCharacter->GetActorLocation();
FVector ForwardVector = PlayerCharacter->GetActorForwardVector();
FVector LineEnd = LineStart + (ForwardVector * MaxRange); FVector LineEnd = LineStart + (ForwardVector * MaxRange);
FHitResult HitResult; FHitResult HitResult;
FCollisionQueryParams QueryParams; FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(Owner); QueryParams.AddIgnoredActor(PlayerCharacter);
// Strza³
bool bHit = GetWorld()->LineTraceSingleByChannel(HitResult, LineStart, LineEnd, ECC_Visibility, QueryParams); bool bHit = GetWorld()->LineTraceSingleByChannel(HitResult, LineStart, LineEnd, ECC_Visibility, QueryParams);
if (bHit && HitResult.GetActor() && HitResult.GetActor()->Implements<UDamageable>()) if (bHit && HitResult.GetActor() && HitResult.GetActor()->Implements<UDamageable>())
{ {
IDamageable::Execute_TakeDamage(HitResult.GetActor(), DamageValue); IDamageable::Execute_TakeDamage(HitResult.GetActor(), DamageValue);
UE_LOG(LogTemp, Warning, TEXT("Shoot")); UE_LOG(LogTemp, Display, TEXT("Shoot. Ammo: %d/%d"), CurrentAmmo, MaxAmmo); // Docelowo tutaj wywo³anie UI aktualizuj¹ce stan ammo
} }
PlayerCharacter->GetWorldTimerManager().SetTimer(ShootCooldownTimer, this, &UShootingComponent::ResetFireCooldown, FireRateCooldown, false);
// Odrzut
FVector RecoilDirection = -PlayerCharacter->GetActorForwardVector();
PlayerCharacter->LaunchCharacter(RecoilDirection * RecoilForce, true, false);
// DEBUG
if (bShowDebugLine) if (bShowDebugLine)
DrawDebugLine(GetWorld(), LineStart, LineEnd, FColor::Red, false, 1.0f, 0, 1.0f); DrawDebugLine(GetWorld(), LineStart, LineEnd, FColor::Red, false, 1.0f, 0, 1.0f);
} }
void UShootingComponent::Reload()
{
if (bIsReloading) return;
bIsReloading = true;
CurrentAmmo = MaxAmmo;
PlayerCharacter->GetWorldTimerManager().SetTimer(ReloadTimer, this, &UShootingComponent::ReloadCompleted, ReloadTime, false);
UE_LOG(LogTemp, Display, TEXT("Reloaded. Ammo: %d/%d"), CurrentAmmo, MaxAmmo); // Docelowo tutaj wywo³anie UI aktualizuj¹ce stan ammo
}
void UShootingComponent::ResetFireCooldown()
{
bCanShoot = true;
}
void UShootingComponent::ReloadCompleted()
{
bIsReloading = false;
}
// Called every frame // Called every frame
void UShootingComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) void UShootingComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)

View File

@ -48,7 +48,6 @@ void AExoPlayerController::SetupInputComponent()
EnhancedInputComponent->BindAction(InteractAction, ETriggerEvent::Triggered, this, &AExoPlayerController::Interact); EnhancedInputComponent->BindAction(InteractAction, ETriggerEvent::Triggered, this, &AExoPlayerController::Interact);
EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerJump); EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerJump);
EnhancedInputComponent->BindAction(DodgeAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerDodge); EnhancedInputComponent->BindAction(DodgeAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerDodge);
//EnhancedInputComponent->BindAction(, ETriggerEvent::Started, this, &AExoPlayerController::ResetDodge);
EnhancedInputComponent->BindAction(CrouchAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerCrouch); EnhancedInputComponent->BindAction(CrouchAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerCrouch);
EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerSprint); EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerSprint);
EnhancedInputComponent->BindAction(ShootAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerShoot); EnhancedInputComponent->BindAction(ShootAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerShoot);
@ -152,5 +151,5 @@ void AExoPlayerController::PlayerChangeWeapon()
void AExoPlayerController::PlayerReload() void AExoPlayerController::PlayerReload()
{ {
ShootingComponent->Reload();
} }

View File

@ -4,6 +4,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Components/ActorComponent.h" #include "Components/ActorComponent.h"
#include <Characters/ExoPlayerCharacter.h>
#include "Interfaces/Damageable.h" #include "Interfaces/Damageable.h"
#include "ShootingComponent.generated.h" #include "ShootingComponent.generated.h"
@ -23,9 +24,27 @@ public:
UPROPERTY(EditAnywhere, Category = "Shooting") UPROPERTY(EditAnywhere, Category = "Shooting")
float DamageValue = 100.0f; float DamageValue = 100.0f;
UPROPERTY(EditAnywhere, Category = "Shooting")
float FireRateCooldown = 1.0f;
UPROPERTY(EditAnywhere, Category = "Shooting")
float RecoilForce = 50.0f;
UPROPERTY(EditAnywhere, Category = "Shooting")
float ReloadTime = 3.0f;
UPROPERTY(EditAnywhere, Category = "Ammo")
int32 CurrentAmmo = 10;
UPROPERTY(EditAnywhere, Category = "Ammo")
int32 MaxAmmo = 10;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Debug") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Debug")
bool bShowDebugLine = true; bool bShowDebugLine = true;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Character")
TObjectPtr<AExoPlayerCharacter> PlayerCharacter;
protected: protected:
// Called when the game starts // Called when the game starts
virtual void BeginPlay() override; virtual void BeginPlay() override;
@ -37,6 +56,21 @@ public:
UFUNCTION(Category = "Shooting") UFUNCTION(Category = "Shooting")
void Shoot(); void Shoot();
//UFUNCTION(Category = "Shooting") UFUNCTION(Category = "Shooting")
//void Reload(); void Reload();
private:
void ResetFireCooldown();
void ReloadCompleted();
FTimerHandle ShootCooldownTimer;
FTimerHandle ReloadTimer;
UPROPERTY(EditAnywhere, Category = "Shooting")
bool bCanShoot = true;
UPROPERTY(EditAnywhere, Category = "Reloading")
bool bIsReloading = false;
}; };