feat: add weapon change

This commit is contained in:
Kubson96 2025-03-23 21:47:10 +01:00
parent debe01abd2
commit ae66d9790a
11 changed files with 105 additions and 54 deletions

Binary file not shown.

View File

@ -3,8 +3,6 @@
#include "Characters/Components/ShootingComponent.h" #include "Characters/Components/ShootingComponent.h"
#include "KismetTraceUtils.h"
// Sets default values for this component's properties // Sets default values for this component's properties
UShootingComponent::UShootingComponent() UShootingComponent::UShootingComponent()
{ {
@ -27,13 +25,13 @@ void UShootingComponent::BeginPlay()
void UShootingComponent::Shoot() void UShootingComponent::Shoot()
{ {
if (!bIsHoldingGun || CurrentAmmo == 0 || bIsReloading || !bCanShoot) return; if (!IsValid(CurrentGun) || CurrentGun->CurrentAmmo == 0 || bIsReloading || !bCanShoot) return;
APawn* PawnOwner = Cast<APawn>(PlayerCharacter); APawn* PawnOwner = Cast<APawn>(PlayerCharacter);
if (!PawnOwner || !PawnOwner->GetController()) return; if (!PawnOwner || !PawnOwner->GetController()) return;
bCanShoot = false; bCanShoot = false;
CurrentAmmo--; CurrentGun->CurrentAmmo--;
FVector ViewLocation; FVector ViewLocation;
FRotator ViewRotation; FRotator ViewRotation;
@ -41,7 +39,7 @@ void UShootingComponent::Shoot()
FVector ForwardVector = ViewRotation.Vector(); FVector ForwardVector = ViewRotation.Vector();
FVector LineStart = ViewLocation; //PlayerCharacter->GetActorLocation(); FVector LineStart = ViewLocation; //PlayerCharacter->GetActorLocation();
FVector LineEnd = LineStart + (ForwardVector * MaxRange); FVector LineEnd = LineStart + (ForwardVector * CurrentGun->MaxRange);
FHitResult HitResult; FHitResult HitResult;
FCollisionQueryParams QueryParams; FCollisionQueryParams QueryParams;
@ -52,19 +50,19 @@ void UShootingComponent::Shoot()
if (bHit && HitResult.GetActor() && HitResult.GetActor()->Implements<UDamageable>()) if (bHit && HitResult.GetActor() && HitResult.GetActor()->Implements<UDamageable>())
{ {
IDamageable::Execute_TakeDamage(HitResult.GetActor(), FireDamageValue); IDamageable::Execute_TakeDamage(HitResult.GetActor(), CurrentGun->DamageValue);
UE_LOG(LogTemp, Display, TEXT("Shoot. Ammo: %d/%d"), CurrentAmmo, MaxAmmo); // Docelowo tutaj wywo<77>anie UI aktualizuj<75>ce stan ammo UE_LOG(LogTemp, Display, TEXT("Shoot. Ammo: %d/%d"), CurrentGun->CurrentAmmo, CurrentGun->MaxAmmo); // Docelowo tutaj wywo<77>anie UI aktualizuj<75>ce stan ammo
} }
PlayerCharacter->GetWorldTimerManager().SetTimer(ShootCooldownTimer, this, &UShootingComponent::ResetFireCooldown, FireRateCooldown, false); PlayerCharacter->GetWorldTimerManager().SetTimer(ShootCooldownTimer, this, &UShootingComponent::ResetFireCooldown, CurrentGun->FireRateCooldown, false);
// Odrzut // Odrzut
float RecoilPitch = FMath::RandRange(-1.0f, -0.5f); float RecoilPitch = FMath::RandRange(-1.0f, -0.5f);
float RecoilYaw = FMath::RandRange(-0.5f, 0.5f); float RecoilYaw = FMath::RandRange(-0.5f, 0.5f);
PlayerCharacter->AddControllerPitchInput(RecoilPitch * RecoilForceMultiplier); PlayerCharacter->AddControllerPitchInput(RecoilPitch * CurrentGun->RecoilForceMultiplier);
PlayerCharacter->AddControllerYawInput(RecoilYaw * RecoilForceMultiplier); PlayerCharacter->AddControllerYawInput(RecoilYaw * CurrentGun->RecoilForceMultiplier);
// DEBUG // DEBUG
if (bShowDebugLine) if (bShowDebugLine)
@ -73,7 +71,6 @@ void UShootingComponent::Shoot()
void UShootingComponent::MeleAttack() void UShootingComponent::MeleAttack()
{ {
FVector ForwardVector = PlayerCharacter->GetActorForwardVector(); FVector ForwardVector = PlayerCharacter->GetActorForwardVector();
FVector ViewLocation; FVector ViewLocation;
FRotator ViewRotation; FRotator ViewRotation;
@ -85,7 +82,8 @@ void UShootingComponent::MeleAttack()
FCollisionQueryParams QueryParams; FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(PlayerCharacter); QueryParams.AddIgnoredActor(PlayerCharacter);
//DrawDebugLine(GetWorld(), ViewLocation, EndVector, FColor::Red, false, 1.0f, 0, 1.0f); if (bShowDebugLine)
DrawDebugLine(GetWorld(), ViewLocation, EndVector, FColor::Red, false, 1.0f, 0, 1.0f);
if (GetWorld()->LineTraceSingleByChannel(Hit, ViewLocation, EndVector, ECC_Visibility, QueryParams)) if (GetWorld()->LineTraceSingleByChannel(Hit, ViewLocation, EndVector, ECC_Visibility, QueryParams))
{ {
@ -94,43 +92,45 @@ void UShootingComponent::MeleAttack()
IDamageable::Execute_TakeDamage(Hit.GetActor(), MeleDamageValue); IDamageable::Execute_TakeDamage(Hit.GetActor(), MeleDamageValue);
} }
} }
} }
void UShootingComponent::Reload() void UShootingComponent::Reload()
{ {
if (!bIsHoldingGun || bIsReloading) return; if (!IsValid(CurrentGun) || bIsReloading) return;
bIsReloading = true; bIsReloading = true;
CurrentAmmo = MaxAmmo; CurrentGun->CurrentAmmo = CurrentGun->MaxAmmo;
PlayerCharacter->GetWorldTimerManager().SetTimer(ReloadTimer, this, &UShootingComponent::ReloadCompleted, ReloadTime, false); PlayerCharacter->GetWorldTimerManager().SetTimer(ReloadTimer, this, &UShootingComponent::ReloadCompleted, CurrentGun->ReloadTime, false);
UE_LOG(LogTemp, Display, TEXT("Reloaded. Ammo: %d/%d"), CurrentAmmo, MaxAmmo); // Docelowo tutaj wywo<77>anie UI aktualizuj<75>ce stan ammo UE_LOG(LogTemp, Display, TEXT("Reloaded. Ammo: %d/%d"), CurrentGun->CurrentAmmo, CurrentGun->MaxAmmo); // Docelowo tutaj wywo<77>anie UI aktualizuj<75>ce stan ammo
} }
void UShootingComponent::PickUpGun(AGunBase* gunItem) void UShootingComponent::PickUpGun(AGunBase* gunItem)
{ {
if (bIsHoldingGun) if (IsValid(CurrentGun) && IsValid(SecondaryGun))
DropGun(); DropGun();
bIsHoldingGun = true; AGunBase* NewGun = NewObject<AGunBase>();
HoldingGunClass = gunItem->GetClass();
MaxRange = gunItem->MaxRange; NewGun->MaxRange = gunItem->MaxRange;
FireDamageValue = gunItem->DamageValue; NewGun->DamageValue = gunItem->DamageValue;
FireRateCooldown = gunItem->FireRateCooldown; NewGun->FireRateCooldown = gunItem->FireRateCooldown;
RecoilForceMultiplier = gunItem->RecoilForceMultiplier; NewGun->RecoilForceMultiplier = gunItem->RecoilForceMultiplier;
ReloadTime = gunItem->ReloadTime; NewGun->ReloadTime = gunItem->ReloadTime;
CurrentAmmo = gunItem->CurrentAmmo; NewGun->CurrentAmmo = gunItem->CurrentAmmo;
MaxAmmo = gunItem->MaxAmmo; NewGun->MaxAmmo = gunItem->MaxAmmo;
NewGun->SceneItemClass = gunItem->GetClass();
if (IsValid(CurrentGun))
SecondaryGun = NewGun;
else
CurrentGun = NewGun;
} }
void UShootingComponent::DropGun() void UShootingComponent::DropGun()
{ {
if (!bIsHoldingGun) return; if (!IsValid(CurrentGun)) return;
FVector ForwardVector = PlayerCharacter->GetActorForwardVector(); FVector ForwardVector = PlayerCharacter->GetActorForwardVector();
FVector PlayerPos = PlayerCharacter->GetActorLocation(); FVector PlayerPos = PlayerCharacter->GetActorLocation();
@ -139,19 +139,20 @@ void UShootingComponent::DropGun()
FTransform DroppedGunTransform = PlayerCharacter->GetActorTransform(); FTransform DroppedGunTransform = PlayerCharacter->GetActorTransform();
DroppedGunTransform.SetLocation(DroppedGunPos); DroppedGunTransform.SetLocation(DroppedGunPos);
AGunBase* DroppedGun = GetWorld()->SpawnActor<AGunBase>(HoldingGunClass, DroppedGunTransform); AGunBase* DroppedGun = GetWorld()->SpawnActor<AGunBase>(CurrentGun->SceneItemClass, DroppedGunTransform);
if (DroppedGun) if (DroppedGun)
{ {
DroppedGun->MaxRange = MaxRange; DroppedGun->MaxRange = CurrentGun->MaxRange;
DroppedGun->DamageValue = FireDamageValue; DroppedGun->DamageValue = CurrentGun->DamageValue;
DroppedGun->FireRateCooldown = FireRateCooldown; DroppedGun->FireRateCooldown = CurrentGun->FireRateCooldown;
DroppedGun->RecoilForceMultiplier = RecoilForceMultiplier; DroppedGun->RecoilForceMultiplier = CurrentGun->RecoilForceMultiplier;
DroppedGun->ReloadTime = ReloadTime; DroppedGun->ReloadTime = CurrentGun->ReloadTime;
DroppedGun->CurrentAmmo = CurrentAmmo; DroppedGun->CurrentAmmo = CurrentGun->CurrentAmmo;
DroppedGun->MaxAmmo = MaxAmmo; DroppedGun->MaxAmmo = CurrentGun->MaxAmmo;
bIsHoldingGun = false; CurrentGun->Destroy();
CurrentGun = nullptr;
} }
} }
@ -165,6 +166,31 @@ void UShootingComponent::ReloadCompleted()
bIsReloading = false; bIsReloading = false;
} }
void UShootingComponent::SelectGun(bool bSelectFirstSlot)
{
if (bSelectFirstSlot != bIsFirstGunSelected)
SwitchGun();
}
void UShootingComponent::SwitchGun()
{
AGunBase* temp = CurrentGun;
CurrentGun = SecondaryGun;
SecondaryGun = temp;
bIsFirstGunSelected = !bIsFirstGunSelected;
// Debug info
if (bIsFirstGunSelected)
{
UE_LOG(LogTemp, Display, TEXT("Zmiana broni na broń 1"));
}
else
{
UE_LOG(LogTemp, Display, TEXT("Zmiana broni na broń 2"));
}
}
// 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

@ -60,6 +60,8 @@ void AExoPlayerController::SetupInputComponent()
EnhancedInputComponent->BindAction(AimAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerAim); EnhancedInputComponent->BindAction(AimAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerAim);
EnhancedInputComponent->BindAction(MeleAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerMeleAttack); EnhancedInputComponent->BindAction(MeleAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerMeleAttack);
EnhancedInputComponent->BindAction(ChangeWeaponAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerChangeWeapon); EnhancedInputComponent->BindAction(ChangeWeaponAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerChangeWeapon);
EnhancedInputComponent->BindAction(SelectFirstWeaponAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerSelectFirstWeapon);
EnhancedInputComponent->BindAction(SelectSecondWeaponAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerSelectSecondWeapon);
EnhancedInputComponent->BindAction(DropWeaponAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerDropWeapon); EnhancedInputComponent->BindAction(DropWeaponAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerDropWeapon);
EnhancedInputComponent->BindAction(ReloadAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerReload); EnhancedInputComponent->BindAction(ReloadAction, ETriggerEvent::Started, this, &AExoPlayerController::PlayerReload);
} }
@ -169,7 +171,17 @@ void AExoPlayerController::PlayerMeleAttack()
void AExoPlayerController::PlayerChangeWeapon() void AExoPlayerController::PlayerChangeWeapon()
{ {
ShootingComponent->SwitchGun();
}
void AExoPlayerController::PlayerSelectFirstWeapon()
{
ShootingComponent->SelectGun(true);
}
void AExoPlayerController::PlayerSelectSecondWeapon()
{
ShootingComponent->SelectGun(false);
} }
void AExoPlayerController::PlayerDropWeapon() void AExoPlayerController::PlayerDropWeapon()

View File

@ -48,33 +48,32 @@ public:
UFUNCTION(Category = "Shooting") UFUNCTION(Category = "Shooting")
void DropGun(); void DropGun();
UFUNCTION(Category = "Shooting")
void SwitchGun();
UFUNCTION(Category = "Shooting")
void SelectGun(bool bSelectFirstSlot);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Shooting") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Shooting")
float DropGunRange = 20.0f; float DropGunRange = 20.0f;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mele Attack") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Mele Attack")
float MeleRange = 75.f; float MeleRange = 75.f;
AGunBase* CurrentGun = nullptr;
AGunBase* SecondaryGun = nullptr;
private: private:
void ResetFireCooldown(); void ResetFireCooldown();
void ReloadCompleted(); void ReloadCompleted();
FTimerHandle ShootCooldownTimer; FTimerHandle ShootCooldownTimer;
FTimerHandle ReloadTimer; FTimerHandle ReloadTimer;
bool bIsHoldingGun = false;
TSubclassOf<AActor> HoldingGunClass;
bool bCanShoot = true; bool bCanShoot = true;
bool bIsReloading = false; bool bIsReloading = false;
bool bIsFirstGunSelected = true;
float MaxRange = 2000.0f;
float FireDamageValue = 100.0f;
float MeleDamageValue = 50.f; float MeleDamageValue = 50.f;
float FireRateCooldown = 1.0f;
float RecoilForceMultiplier = 1.0f;
float ReloadTime = 3.0f;
int32 CurrentAmmo = 10;
int32 MaxAmmo = 10;
}; };

View File

@ -37,6 +37,8 @@ public:
UPROPERTY(EditAnywhere, Category = "Ammo") UPROPERTY(EditAnywhere, Category = "Ammo")
int32 MaxAmmo = 10; int32 MaxAmmo = 10;
TSubclassOf<AActor> SceneItemClass;
protected: protected:
// Called when the game starts or when spawned // Called when the game starts or when spawned
virtual void BeginPlay() override; virtual void BeginPlay() override;

View File

@ -69,8 +69,14 @@ protected:
void PlayerMeleAttack(); // V - nieprzypisane void PlayerMeleAttack(); // V - nieprzypisane
UFUNCTION(BlueprintCallable, Category = "Input") UFUNCTION(BlueprintCallable, Category = "Input")
void PlayerChangeWeapon(); // 1\2\MouseScroll - nieprzypisane void PlayerChangeWeapon(); // MouseScroll
UFUNCTION(BlueprintCallable, Category = "Input")
void PlayerSelectFirstWeapon(); // 1
UFUNCTION(BlueprintCallable, Category = "Input")
void PlayerSelectSecondWeapon(); // 2
UFUNCTION(BlueprintCallable, Category = "Input") UFUNCTION(BlueprintCallable, Category = "Input")
void PlayerDropWeapon(); // F void PlayerDropWeapon(); // F
@ -124,6 +130,12 @@ protected:
UPROPERTY(EditAnywhere, Category = "Input") UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> ChangeWeaponAction; TObjectPtr<UInputAction> ChangeWeaponAction;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> SelectFirstWeaponAction;
UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> SelectSecondWeaponAction;
UPROPERTY(EditAnywhere, Category = "Input") UPROPERTY(EditAnywhere, Category = "Input")
TObjectPtr<UInputAction> DropWeaponAction; TObjectPtr<UInputAction> DropWeaponAction;