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());
|
FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh());
|
||||||
FVector Start = SocketTransform.GetLocation();
|
FVector Start = SocketTransform.GetLocation();
|
||||||
FVector End = Start + (HitTarget - Start) * 1.25f;
|
|
||||||
|
|
||||||
FHitResult FireHit;
|
FHitResult FireHit;
|
||||||
UWorld* World = GetWorld();
|
WeaponTraceHit(Start, HitTarget, FireHit);
|
||||||
if (World)
|
|
||||||
|
ABlasterCharacter* BlasterCharacter = Cast<ABlasterCharacter>(FireHit.GetActor());
|
||||||
|
if (BlasterCharacter && HasAuthority() && InstigatorController)
|
||||||
{
|
{
|
||||||
World->LineTraceSingleByChannel(
|
UGameplayStatics::ApplyDamage(
|
||||||
FireHit,
|
BlasterCharacter,
|
||||||
Start,
|
Damage,
|
||||||
End,
|
InstigatorController,
|
||||||
ECC_Visibility
|
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)
|
if (MuzzleFlash)
|
||||||
{
|
{
|
||||||
UGameplayStatics::SpawnEmitterAtLocation(
|
UGameplayStatics::SpawnEmitterAtLocation(
|
||||||
World,
|
GetWorld(),
|
||||||
MuzzleFlash,
|
MuzzleFlash,
|
||||||
SocketTransform
|
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 AHitScanWeapon::TraceEndWithScatter(const FVector& TraceStart, const FVector& HitTarget)
|
||||||
{
|
{
|
||||||
FVector ToTargetNormalized = (HitTarget - TraceStart).GetSafeNormal();
|
FVector ToTargetNormalized = (HitTarget - TraceStart).GetSafeNormal();
|
||||||
|
@ -111,6 +115,7 @@ FVector AHitScanWeapon::TraceEndWithScatter(const FVector& TraceStart, const FVe
|
||||||
FVector EndLoc = SphereCenter + RandVec;
|
FVector EndLoc = SphereCenter + RandVec;
|
||||||
FVector ToEndLoc = EndLoc - TraceStart;
|
FVector ToEndLoc = EndLoc - TraceStart;
|
||||||
|
|
||||||
|
/*
|
||||||
DrawDebugSphere(GetWorld(), SphereCenter, SphereRadius, 12, FColor::Red, true);
|
DrawDebugSphere(GetWorld(), SphereCenter, SphereRadius, 12, FColor::Red, true);
|
||||||
DrawDebugSphere(GetWorld(), ToEndLoc, 4.f, 12, FColor::Blue, true);
|
DrawDebugSphere(GetWorld(), ToEndLoc, 4.f, 12, FColor::Blue, true);
|
||||||
DrawDebugLine(
|
DrawDebugLine(
|
||||||
|
@ -120,6 +125,6 @@ FVector AHitScanWeapon::TraceEndWithScatter(const FVector& TraceStart, const FVe
|
||||||
FColor::Cyan,
|
FColor::Cyan,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
return FVector(TraceStart + ToEndLoc * TRACE_LENGTH / ToEndLoc.Size());
|
return FVector(TraceStart + ToEndLoc * TRACE_LENGTH / ToEndLoc.Size());
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,18 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
FVector TraceEndWithScatter(const FVector& TraceStart, const FVector& HitTarget);
|
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)
|
UPROPERTY(EditAnywhere)
|
||||||
float Damage = 20.f;
|
float Damage = 20.f;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere)
|
private:
|
||||||
UParticleSystem* ImpactParticles;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere)
|
UPROPERTY(EditAnywhere)
|
||||||
UParticleSystem* BeamParticles;
|
UParticleSystem* BeamParticles;
|
||||||
|
@ -39,9 +43,6 @@ private:
|
||||||
UPROPERTY(EditAnywhere)
|
UPROPERTY(EditAnywhere)
|
||||||
USoundCue* FireSound;
|
USoundCue* FireSound;
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere)
|
|
||||||
USoundCue* HitSound;
|
|
||||||
|
|
||||||
// Trace end with scatter
|
// Trace end with scatter
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, Category = "Weapon Scatter")
|
UPROPERTY(EditAnywhere, Category = "Weapon Scatter")
|
||||||
|
|
|
@ -21,9 +21,57 @@ void AShotgun::Fire(const FVector& HitTarget)
|
||||||
FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh());
|
FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh());
|
||||||
FVector Start = SocketTransform.GetLocation();
|
FVector Start = SocketTransform.GetLocation();
|
||||||
|
|
||||||
|
TMap<ABlasterCharacter*, uint32> HitMap;
|
||||||
for (uint32 i = 0; i < NumberOfPellets; i++)
|
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