In ULyraGameplayAbility_RangedWeapon there is this ELyraAbilityTargetingSource enum that i’m mostly interested in using WeaponTowardsFocus from it in order to hit walls if it’s in the way between the gun and the target. Currently if you change
The trace would start from the actor and not from the weapon, and the trace end is not accurate at all, mostly because the GetWeaponTargetingSourceLocation function is still not fully implemented to handle all the cases.
Modifying the WeaponTrace function actually did the trick
FHitResult ULyraGameplayAbility_RangedWeapon::WeaponTrace(const FVector& StartTrace, const FVector& EndTrace, float SweepRadius, bool bIsSimulated, OUT TArray<FHitResult>& OutHitResults) const
{
TArray<FHitResult> HitResults;
FCollisionQueryParams TraceParams(SCENE_QUERY_STAT(WeaponTrace), /*bTraceComplex=*/ true, /*IgnoreActor=*/ GetAvatarActorFromActorInfo());
TraceParams.bReturnPhysicalMaterial = true;
AddAdditionalTraceIgnoreActors(TraceParams);
//TraceParams.bDebugQuery = true;
const ECollisionChannel TraceChannel = DetermineTraceChannel(TraceParams, bIsSimulated);
if (SweepRadius > 0.0f)
{
GetWorld()->SweepMultiByChannel(HitResults, StartTrace, EndTrace, FQuat::Identity, TraceChannel, FCollisionShape::MakeSphere(SweepRadius), TraceParams);
}
else
{
GetWorld()->LineTraceMultiByChannel(HitResults, StartTrace, EndTrace, TraceChannel, TraceParams);
}
FHitResult Hit(ForceInit);
if (HitResults.Num() > 0)
{
// Filter the output list to prevent multiple hits on the same actor;
// this is to prevent a single bullet dealing damage multiple times to
// a single actor if using an overlap trace
for (FHitResult& CurHitResult : HitResults)
{
auto Pred = [&CurHitResult](const FHitResult& Other)
{
return Other.HitObjectHandle == CurHitResult.HitObjectHandle;
};
if (!OutHitResults.ContainsByPredicate(Pred))
{
OutHitResults.Add(CurHitResult);
}
}
Hit = OutHitResults.Last();
// Perform an additional line trace to check for obstacles ignoring the valid target
FHitResult ObstacleHit;
if (Hit.GetActor())
{
TraceParams.AddIgnoredActor(Hit.GetActor());
}
FVector StartTrace_Obstacle = StartTrace;
if (AActor* WeaponActor = GetFirstSpawnedWeaponActor())
{
StartTrace_Obstacle = WeaponActor->GetActorLocation();
}
bool bHitObstacle = GetWorld()->LineTraceSingleByChannel(ObstacleHit, StartTrace_Obstacle, Hit.ImpactPoint, TraceChannel, TraceParams);
if (bHitObstacle && ObstacleHit.GetActor())
{
// If an obstacle is hit, clear the OutHitResults and add the obstacle hit
OutHitResults.Empty();
OutHitResults.Add(ObstacleHit);
Hit = ObstacleHit;
}
}
else
{
Hit.TraceStart = StartTrace;
Hit.TraceEnd = EndTrace;
}
return Hit;
}
Can add a bool for whether the weapon should do the check for the obstacle or not etc…