ExoWest/Source/Exo/Private/Characters/Components/ShootingComponent.cpp
Kubson96 0f2fac10bd feat: add recoil, fire rate and reloading
Added recoil force while shooting
Added fire rate system
Implement reloading
2025-02-22 01:28:07 +01:00

92 lines
2.7 KiB
C++

// Fill out your copyright notice in the Description page of Project Settings.
#include "Characters/Components/ShootingComponent.h"
// Sets default values for this component's properties
UShootingComponent::UShootingComponent()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
}
// Called when the game starts
void UShootingComponent::BeginPlay()
{
Super::BeginPlay();
PlayerCharacter = Cast<AExoPlayerCharacter>(GetOwner());
}
void UShootingComponent::Shoot()
{
if (CurrentAmmo == 0 || bIsReloading || !bCanShoot) return;
bCanShoot = false;
CurrentAmmo--;
FVector LineStart = PlayerCharacter->GetActorLocation();
FVector ForwardVector = PlayerCharacter->GetActorForwardVector();
FVector LineEnd = LineStart + (ForwardVector * MaxRange);
FHitResult HitResult;
FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(PlayerCharacter);
// Strza³
bool bHit = GetWorld()->LineTraceSingleByChannel(HitResult, LineStart, LineEnd, ECC_Visibility, QueryParams);
if (bHit && HitResult.GetActor() && HitResult.GetActor()->Implements<UDamageable>())
{
IDamageable::Execute_TakeDamage(HitResult.GetActor(), DamageValue);
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)
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
void UShootingComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
// ...
}