138 - Weapon Scatter
This commit is contained in:
parent
c619f07b1e
commit
08a1b89702
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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<ABlasterCharacter>(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<ABlasterCharacter>(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();
|
||||
|
@ -111,6 +115,7 @@ FVector AHitScanWeapon::TraceEndWithScatter(const FVector& TraceStart, const FVe
|
|||
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());
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
UParticleSystem* ImpactParticles;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
USoundCue* HitSound;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
float Damage = 20.f;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
UParticleSystem* ImpactParticles;
|
||||
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")
|
||||
|
|
|
@ -21,9 +21,57 @@ void AShotgun::Fire(const FVector& HitTarget)
|
|||
FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh());
|
||||
FVector Start = SocketTransform.GetLocation();
|
||||
|
||||
TMap<ABlasterCharacter*, uint32> HitMap;
|
||||
for (uint32 i = 0; i < NumberOfPellets; i++)
|
||||
{
|
||||
FVector End = TraceEndWithScatter(Start, HitTarget);
|
||||
FHitResult FireHit;
|
||||
WeaponTraceHit(Start, HitTarget, FireHit);
|
||||
|
||||
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(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()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue