Download

GetHitResultAtScreenPosition failes with empty exception

Hey guys i try to use GetHitResultAtScreenPosition but i can’t get it to work. When executed i get an exception with no info about the problem.
I’m executing this code from my pawn and i’m not using a custom PlayerController but i also tryed making my own Player Controller and execute the code there but it failed the same way.



APlayerController* PlayerController;
int32 ViewportSizeX;
int32 ViewportSizeY;

PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);
PlayerController->GetViewportSize(ViewportSizeX, ViewportSizeY);

const FVector2D Position(0.5 * ViewportSizeX, 0.5 * ViewportSizeY);
FHitResult HitResult;
bool Success = PlayerController->GetHitResultAtScreenPosition(Position, ECollisionChannel::ECC_Visibility, true, HitResult);

if (Success)
{
    UE_LOG(ALICE_RT_PAWN, Warning, TEXT("HIT"));
}


I also tried some different parameters but it’s always the same:

Alternative 1:



TArray<TEnumAsByte<EObjectTypeQuery>> ObjectTypes;
ObjectTypes.Add(UEngineTypes::ConvertToObjectType(ECollisionChannel::ECC_WorldStatic));
bool Success = PlayerController->GetHitResultAtScreenPosition(Position, ObjectTypes, false, HitResult);


Alternative 2:



const ECollisionChannel CollisionChannel = ECollisionChannel::ECC_Visibility;
bool Success = PlayerController->GetHitResultAtScreenPosition(Position, CollisionChannel, false, HitResult);


Alternative 3:



FCollisionQueryParams CollisionQueryParams(TEXT("CollisionQuery"), true, this);
bool Success = PlayerController->GetHitResultAtScreenPosition(Position, ECollisionChannel::ECC_WorldStatic, CollisionQueryParams, HitResult);


I hope anyone can help me!

Thanks a lot anyone.

Cheers,
Dennis

This is how we do it. This casts through the center of the screen and returns a HitResult, from which you get an Actor and Component to do something with.




/**
* Looks for interactive objects.
* Called every tick.
*/
void PlayerState_Walking::LookForInteractiveObjects()
{
 // cannot ray trace without player controller
 if (_playerController == nullptr)
 {
  return;
 }

 // get current camera location and rotation
 FVector cameraLocation = _playerController->PlayerCameraManager->GetCameraLocation();
 FRotator cameraRotation = _playerController->PlayerCameraManager->GetCameraRotation();

 // calculate ray start point, ray end point, hit result, collision parameters
 // ray start point is the camera location
 // ray end point is a ray cast through the middle of the screen
 FVector traceStartLocation = cameraLocation;
 FVector traceEndLocation = cameraLocation + MAXIMUM_INTERACTION_DISTANCE * cameraRotation.Vector().GetSafeNormal();
 FHitResult traceHitResult(ForceInit);
 FCollisionQueryParams traceParameters(FName("Trace"), true);

 // do ray trace
 _playerController->GetWorld()->LineTraceSingleByChannel(traceHitResult,  // result
               traceStartLocation, // start
               traceEndLocation, // end
               ECC_Pawn,   // collision channel
               traceParameters); // trace parameters

 // get unreal trace actor and component
 AActor* traceActor = traceHitResult.GetActor();
 UPrimitiveComponent* traceComponent = traceHitResult.GetComponent();

 // check for hit and update selected objects
 YourClass* myHitActor = Cast<YourClass>(traceHitResult.GetActor());
 if (myHitActor!= nullptr)
 {
    // your code here to do something with the hit object
 }
}


Hey Jocko,

thanks for your response. a line trace can get me half way but i need to deproject from the 2D coordinates first and then run the trace from the camera origin through the deprojected position to get to the same result as GetHitResultAtScreenPosition and i think that’s what it does behind the scene anyways .

Now the thing is that i tried DeprojectScreenPositionToWorld and it failed with the same error but thanks to trying this approach i found my error. The function was in my pawn but it was called from another class so i followed the trail and the initial call was made from an FRunnable so i was on another thread without noticing so calling anything on the game thread failed.

So thanks for your help and this is solved now