In my project, I encountered an issue where really small meshes cannot be hit even when they are scaled to a normal size. The meshes are loaded at runtime using ProceduralMeshComponent
, and I apply different scale factors to them.
To demonstrate the problem, I have created a demo project.
In the project, there are three meshes:
- The first mesh has a size of 100 and a scale of 1.
- The second mesh has a size of 1 and a scale of 100.
- The third mesh has a size of 0.005 and a scale of 20000.
Here is the code snippet that spawns and sets up the meshes:
// HitTestGameMode.cpp
ARuntimeMeshActor* Actor1 = GetWorld()->SpawnActor<ARuntimeMeshActor>(SpawnParams);
Actor1->CreateCube(100);
Actor1->SetActorLocationAndRotation(FVector(0.0f, 0.0f, -150.0f), FRotator(0.0f, 0.0f, 0.0f));
Actor1->SetActorScale3D(FVector(1, 1, 1));
ARuntimeMeshActor* Actor2 = GetWorld()->SpawnActor<ARuntimeMeshActor>(SpawnParams);
Actor2->CreateCube(1);
Actor2->SetActorLocationAndRotation(FVector(0.0f, 0.0f, 0.0f), FRotator(0.0f, 0.0f, 0.0f));
Actor2->SetActorScale3D(FVector(100, 100, 100));
ARuntimeMeshActor* Actor3 = GetWorld()->SpawnActor<ARuntimeMeshActor>(SpawnParams);
Actor3->CreateCube(0.005);
Actor3->SetActorLocationAndRotation(FVector(0.0f, 0.0f, 150.0f), FRotator(0.0f, 0.0f, 0.0f));
Actor3->SetActorScale3D(FVector(20000, 20000, 20000));
The hit test functionality is implemented in the AHitTestPlayerController::HitTest()
function, which is triggered by a click event in the level blueprint:
void AHitTestPlayerController::HitTest(UWorld* world)
{
FVector mousePos, mouseDir;
DeprojectMousePositionToWorld(mousePos, mouseDir);
float maxDist = 1.0e9;
FHitResult hitResult;
bool hit = world->LineTraceSingleByChannel(hitResult, mousePos, mousePos + mouseDir * maxDist, ECollisionChannel::ECC_Visibility);
AActor* hitActor = hitResult.GetActor();
if (hit && hitActor != nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("sx: HitTest result %s"), *hitActor->GetActorLabel());
}
}
In this scenario, the first two cubes can be successfully hit using LineTraceSingleByChannel
, but the third cube cannot.
It seems to be a precision issue, but the vertex value 0.005 does not appear to be below the limitation of a float variable.
I would appreciate any suggestions on how to avoid this issue. Thank you!