diff --git a/Content/Blueprints/Weapon/BP_Pistol.uasset b/Content/Blueprints/Weapon/BP_Pistol.uasset index 735bacb..d44bbb1 100644 Binary files a/Content/Blueprints/Weapon/BP_Pistol.uasset and b/Content/Blueprints/Weapon/BP_Pistol.uasset differ diff --git a/Content/Blueprints/Weapon/BP_Shotgun.uasset b/Content/Blueprints/Weapon/BP_Shotgun.uasset index 1ebcf26..54a43fa 100644 Binary files a/Content/Blueprints/Weapon/BP_Shotgun.uasset and b/Content/Blueprints/Weapon/BP_Shotgun.uasset differ diff --git a/Content/Blueprints/Weapon/BP_SubmachineGun.uasset b/Content/Blueprints/Weapon/BP_SubmachineGun.uasset index f9e2fd0..401e2fc 100644 Binary files a/Content/Blueprints/Weapon/BP_SubmachineGun.uasset and b/Content/Blueprints/Weapon/BP_SubmachineGun.uasset differ diff --git a/Content/Maps/BlasterMap.umap b/Content/Maps/BlasterMap.umap index 49394ae..bc43931 100644 Binary files a/Content/Maps/BlasterMap.umap and b/Content/Maps/BlasterMap.umap differ diff --git a/Source/Blaster/Weapon/HitScanWeapon.cpp b/Source/Blaster/Weapon/HitScanWeapon.cpp index fc1ba2c..c7a6c40 100644 --- a/Source/Blaster/Weapon/HitScanWeapon.cpp +++ b/Source/Blaster/Weapon/HitScanWeapon.cpp @@ -22,72 +22,42 @@ void AHitScanWeapon::Fire(const FVector& HitTarget) { FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh()); FVector Start = SocketTransform.GetLocation(); - FVector End = Start + (HitTarget - Start) * 1.25f; FHitResult FireHit; - UWorld* World = GetWorld(); - if (World) + WeaponTraceHit(Start, HitTarget, FireHit); + + ABlasterCharacter* BlasterCharacter = Cast(FireHit.GetActor()); + if (BlasterCharacter && HasAuthority() && InstigatorController) { - World->LineTraceSingleByChannel( - FireHit, - Start, - End, - ECC_Visibility + UGameplayStatics::ApplyDamage( + BlasterCharacter, + Damage, + InstigatorController, + this, + UDamageType::StaticClass() + ); + } + if (ImpactParticles) + { + UGameplayStatics::SpawnEmitterAtLocation( + GetWorld(), + ImpactParticles, + FireHit.ImpactPoint, + FireHit.ImpactNormal.Rotation() + ); + } + if (HitSound) + { + UGameplayStatics::PlaySoundAtLocation( + this, + HitSound, + FireHit.ImpactPoint ); - FVector BeamEnd = End; - if (FireHit.bBlockingHit) - { - BeamEnd = FireHit.ImpactPoint; - ABlasterCharacter* BlasterCharacter = Cast(FireHit.GetActor()); - if (BlasterCharacter && HasAuthority() && InstigatorController) - { - UGameplayStatics::ApplyDamage( - BlasterCharacter, - Damage, - InstigatorController, - this, - UDamageType::StaticClass() - ); - } - - if (ImpactParticles) - { - UGameplayStatics::SpawnEmitterAtLocation( - World, - ImpactParticles, - FireHit.ImpactPoint, - FireHit.ImpactNormal.Rotation() - ); - } - - if (HitSound) - { - UGameplayStatics::PlaySoundAtLocation( - this, - HitSound, - FireHit.ImpactPoint - ); - } - } - - if (BeamParticles) - { - UParticleSystemComponent* Beam = UGameplayStatics::SpawnEmitterAtLocation( - World, - BeamParticles, - SocketTransform - ); - if (Beam) - { - Beam->SetVectorParameter(FName("Target"), BeamEnd); - } - } } - if (MuzzleFlash) { UGameplayStatics::SpawnEmitterAtLocation( - World, + GetWorld(), MuzzleFlash, SocketTransform ); @@ -103,6 +73,40 @@ void AHitScanWeapon::Fire(const FVector& HitTarget) } } +void AHitScanWeapon::WeaponTraceHit(const FVector& TraceStart, const FVector& HitTarget, FHitResult& OutHit) +{ + UWorld* World = GetWorld(); + if (World) + { + FVector End = bUseScatter ? TraceEndWithScatter(TraceStart, HitTarget) : TraceStart + (HitTarget - TraceStart) * 1.25f; + World->LineTraceSingleByChannel( + OutHit, + TraceStart, + End, + ECC_Visibility + ); + FVector BeamEnd = End; + if (OutHit.bBlockingHit) + { + BeamEnd = OutHit.ImpactPoint; + } + if (BeamParticles) + { + UParticleSystemComponent* Beam = UGameplayStatics::SpawnEmitterAtLocation( + World, + BeamParticles, + TraceStart, + FRotator::ZeroRotator, + true + ); + if (Beam) + { + Beam->SetVectorParameter(FName("Target"), BeamEnd); + } + } + } +} + FVector AHitScanWeapon::TraceEndWithScatter(const FVector& TraceStart, const FVector& HitTarget) { FVector ToTargetNormalized = (HitTarget - TraceStart).GetSafeNormal(); @@ -110,7 +114,8 @@ FVector AHitScanWeapon::TraceEndWithScatter(const FVector& TraceStart, const FVe FVector RandVec = UKismetMathLibrary::RandomUnitVector() * FMath::FRandRange(0.f, SphereRadius); FVector EndLoc = SphereCenter + RandVec; FVector ToEndLoc = EndLoc - TraceStart; - + + /* DrawDebugSphere(GetWorld(), SphereCenter, SphereRadius, 12, FColor::Red, true); DrawDebugSphere(GetWorld(), ToEndLoc, 4.f, 12, FColor::Blue, true); DrawDebugLine( @@ -120,6 +125,6 @@ FVector AHitScanWeapon::TraceEndWithScatter(const FVector& TraceStart, const FVe FColor::Cyan, true ); - + */ return FVector(TraceStart + ToEndLoc * TRACE_LENGTH / ToEndLoc.Size()); } diff --git a/Source/Blaster/Weapon/HitScanWeapon.h b/Source/Blaster/Weapon/HitScanWeapon.h index c21c2df..bb2889c 100644 --- a/Source/Blaster/Weapon/HitScanWeapon.h +++ b/Source/Blaster/Weapon/HitScanWeapon.h @@ -21,14 +21,18 @@ public: protected: FVector TraceEndWithScatter(const FVector& TraceStart, const FVector& HitTarget); + void WeaponTraceHit(const FVector& TraceStart, const FVector& HitTarget, FHitResult& OutHit); -private: - - UPROPERTY(EditAnywhere) - float Damage = 20.f; - UPROPERTY(EditAnywhere) UParticleSystem* ImpactParticles; + + UPROPERTY(EditAnywhere) + USoundCue* HitSound; + + UPROPERTY(EditAnywhere) + float Damage = 20.f; + +private: UPROPERTY(EditAnywhere) UParticleSystem* BeamParticles; @@ -39,9 +43,6 @@ private: UPROPERTY(EditAnywhere) USoundCue* FireSound; - UPROPERTY(EditAnywhere) - USoundCue* HitSound; - // Trace end with scatter UPROPERTY(EditAnywhere, Category = "Weapon Scatter") diff --git a/Source/Blaster/Weapon/Shotgun.cpp b/Source/Blaster/Weapon/Shotgun.cpp index 6c96803..aeac566 100644 --- a/Source/Blaster/Weapon/Shotgun.cpp +++ b/Source/Blaster/Weapon/Shotgun.cpp @@ -10,20 +10,68 @@ void AShotgun::Fire(const FVector& HitTarget) { AWeapon::Fire(HitTarget); - + APawn* OwnerPawn = Cast(GetOwner()); if (OwnerPawn == nullptr) return; AController* InstigatorController = OwnerPawn->GetController(); - + const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName("MuzzleFlash"); if (MuzzleFlashSocket) { FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh()); FVector Start = SocketTransform.GetLocation(); + TMap HitMap; for (uint32 i = 0; i < NumberOfPellets; i++) { - FVector End = TraceEndWithScatter(Start, HitTarget); + FHitResult FireHit; + WeaponTraceHit(Start, HitTarget, FireHit); + + ABlasterCharacter* BlasterCharacter = Cast(FireHit.GetActor()); + if (BlasterCharacter && HasAuthority() && InstigatorController) + { + if (HitMap.Contains(BlasterCharacter)) + { + HitMap[BlasterCharacter]++; + } + else + { + HitMap.Emplace(BlasterCharacter, 1); + } + } + if (ImpactParticles) + { + UGameplayStatics::SpawnEmitterAtLocation( + GetWorld(), + ImpactParticles, + FireHit.ImpactPoint, + FireHit.ImpactNormal.Rotation() + ); + } + if (HitSound) + { + UGameplayStatics::PlaySoundAtLocation( + this, + HitSound, + FireHit.ImpactPoint, + .5f, + FMath::FRandRange(-.5f, .5f) + ); + } + } + + for (auto HitPair : HitMap) + { + if (HitPair.Key && HasAuthority() && InstigatorController) + { + UGameplayStatics::ApplyDamage( + HitPair.Key, + Damage * HitPair.Value, + InstigatorController, + this, + UDamageType::StaticClass() + ); + } } } }