Is there an example of using LineTraceMulti available? Something demonstrating the trace and then going through the results.
I use a LineTraceMulti for a weapon that pierces pawns but not worldstatic objects (so if a pawn is standing in front of another pawn, they’ll both be hit, but if one of them’s behind a wall, it won’t be.)
Collision setup in DefaultEngine.ini looks like this:
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel4,Name="PiercingWeapon",DefaultResponse=ECR_Overlap,bTraceType=True,bStaticObject=False)
+EditProfiles=(Name="BlockAll",CustomResponses=((Channel="PiercingWeapon",Response=ECR_Block)))
So the PiercingWeapon trace channel response by default produces overlapping (non-blocking) hits, but the BlockAll channel will block it.
I define an alias for my trace channel in MyGame.h:
#define COLLISION_WEAPON_PIERCING ECC_GameTraceChannel4
In my weapon, I generate a list of hit results using LineTraceMulti:
TArray<FHitResult> AMyGameWeapon::WeaponTrace_Piercing(const FVector& StartTrace, const FVector& EndTrace) const
{
static FName WeaponFireTag = FName(TEXT("WeaponTrace"));
// Perform trace to retrieve hit info
FCollisionQueryParams TraceParams(WeaponFireTag, true, Instigator);
TraceParams.bTraceAsyncScene = true;
TraceParams.bReturnPhysicalMaterial = true;
TArray<FHitResult> Hits;
GetWorld()->LineTraceMultiByChannel(Hits, StartTrace, EndTrace, COLLISION_WEAPON_PIERCING, TraceParams);
return Hits;
}
And then the weapon can iterate through the results, deal damage, spawn decals and hit effects, etc (ProcessInstantFireHit() in this case is pretty much what you’ll find in ShooterGame’s example):
void AMyGameWeapon::FireWeapon_Instant_Piercing()
{
const FInstantWeaponData InstantConfig = GetCurrentFiringFunctionComponent()->GetInstantConfig();
const int32 RandomSeed = FMath::Rand();
FRandomStream WeaponRandomStream(RandomSeed);
const float CurrentSpread = GetCurrentInstantFireSpread();
const float ConeHalfAngle = FMath::DegreesToRadians(CurrentSpread * 0.5f);
const FVector AimDir = GetAdjustedAim();
const FVector StartTrace = GetCameraDamageStartLocation(AimDir);
const FVector ShootDir = WeaponRandomStream.VRandCone(AimDir, ConeHalfAngle, ConeHalfAngle);
const FVector EndTrace = StartTrace + ShootDir * InstantConfig.WeaponRange;
const TArray<FHitResult> Impacts = WeaponTrace_Piercing(StartTrace, EndTrace);
for (const FHitResult& Impact : Impacts)
{
ProcessInstantFireHit(Impact, StartTrace, ShootDir, RandomSeed, CurrentSpread);
}
CurrentInstantFireSpread = FMath::Min(InstantConfig.FiringSpreadMax, CurrentInstantFireSpread + InstantConfig.FiringSpreadIncrement);
}
Hope this helps!