Create a line trace that returns multiple hits

I want to create a custom line trace that returns all hits along a path.

I think from scanning through the engine code and reading the PhysX documentation here that I want to add the PxHitFlag::eMULTIPLE flag to the RaycastMulti code inside of PhysXCollision.cpp

Is there a way to create my own version of this function without changing the engine code?

I tried to copy out the relevant lines and paste them into a new class but had problems with not being able to see any of the PhysX includes.

Why not just use the engines built in MultiLineTrace function. It does exactly that, returns multiple hits.

It only returns one hit per mesh. I want to return every face that is hit.

I found a solution to this after a little bit of work and some help from Rama’s tutorial on integrating PhysX code in to your project. First off I needed to include the PhysX and APEX modules in my Build.cs

PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "PhysX", "APEX" });

I added the following includes to my class.

#include "PhysXIncludes.h"
#include "PhysicsPublic.h"
#include "PhysXPublic.h"

Then I created the following function.

TArray<FHitResult> UFunctionLibrary::MultiHitTrace(UWorld* World, FVector Start, FVector End)
{
	FVector Delta = End - Start;
	float DeltaMag = Delta.Size();

	FPhysScene* PhysScene = World->GetPhysicsScene();
	PxScene* scene = PhysScene->GetPhysXScene(PST_Sync);
	PxVec3 origin = U2PVector(Start);
	PxVec3 unitDir = U2PVector(Delta / DeltaMag);
	PxReal maxDistance = DeltaMag;

	const PxU32 bufferSize = 256;
	PxRaycastHit hitBuffer[bufferSize];
	PxRaycastBuffer buf(hitBuffer, bufferSize);
	PxHitFlags POutputFlags = PxHitFlag::eMESH_MULTIPLE | PxHitFlag::eMESH_BOTH_SIDES;

	scene->raycast(origin, unitDir, maxDistance, buf, POutputFlags);

	FHitResult HitResult;
	TArray<FHitResult> Hits;

	for (PxU32 i = 0; i < buf.nbTouches; i++)
	{
		HitResult.Location = (P2UVector(buf.touches[i].position));
		PxShape* PShape = buf.touches[i].shape;
		PxU32 FaceIndex = buf.touches[i].faceIndex;
		UPhysicalMaterial* PhysMaterial;

		if (PxMaterial* PxMat = PShape->getMaterialFromInternalFaceIndex(FaceIndex))
		{
			PhysMaterial = FPhysxUserData::Get<UPhysicalMaterial>(PxMat->userData);
			HitResult.PhysMaterial = PhysMaterial;
		}
	}

	return Hits;
}

I only wanted the location of the hit and the physical material so that is all the FHitResult returns.

Hopefully this will be useful to someone in the future. Warning to anyone who wants to use this function, it is a very particular use case that is more expensive than the solutions offered by the engine, for most purposes the LineTrace or MultiLineTrace should suffice.