Stop line tracing when behind an object (wall)

Hello.

I have been trying to find out a solution to a problem I have with LineTraceByObjectType in C++…

My code is as follows:

bool ADkrStoreCharacter::CheckIfItemWithinRange() {
  auto HitResult = LineTraceByChannel(1);
  if (HitResult.GetActor()) {
    return true;
  }
  return false;
}


FHitResult ADkrStoreCharacter::LineTraceByChannel(int Channel) {
  FVector StartLocation;
  FRotator Rotation;
  GetWorld()->GetFirstPlayerController()->GetPlayerViewPoint(StartLocation, Rotation);
  
  auto EndLocation = StartLocation + (Rotation.Vector() * Reach);
  auto QueryParams = FCollisionQueryParams(FName(TEXT("")), false, GetOwner());
  FHitResult HitResult;
  
    switch (Channel) {
    case 1:
      GetWorld()->LineTraceSingleByObjectType(HitResult, StartLocation, EndLocation, FCollisionObjectQueryParams(ECC_PICKUP_CHANNEL), QueryParams);
      break;
    case 2:
      GetWorld()->LineTraceSingleByObjectType(HitResult, StartLocation, EndLocation, FCollisionObjectQueryParams(ECC_SHELF_CHANNEL), QueryParams);
      break;
   
    default:
      break;
    }
  
  return HitResult;
}

And this works perfectly fine as it is. However, I am still able to pick the object ingame through a wall.
I’ve setup my wall’s collision to block everything, even created a separate channel for it…

I’ve tried just using the preset collision profiles using ‘BlockAll’ ‘BlockAllDynamic’ everything that’s got to do with blocking.

I’ve also tried line tracing for the wall’s object type and including it in the CheckIfItemWithinRange method in the condition, however, that line tracing is also triggered when I am looking at the object and the line trace goes through it, not only from the back of the wall…

So in essence - I want the linetracing to stop if it registers a wall first. I am attaching a screenshot of the current behaviour. Is there a way to do it in C++?

When checking if it hits a wall, it outright skips the pickup channel even if I am looking at it, because I guess it traces the wall behind it as well.
Since the posting of the question, I’ve tested with both TraceByChannel and TraceByProfile. They still go right through the wall.

Hi, what should this logic do?

As far as I see it, right now you’re doing a single line trace (that will return its first hit) from the location and rotation of the players view and then you return true if what you hit with that line trace is a valid actor (will also return true if you hit the wall, basically it will return true if it hit anything, since everything you can place in the world inherits from actor), else if it hits nothing you return false.

I have reworded the question, sorry for the confusion.

The function

bool ADkrStoreCharacter::CheckIfItemWithinRange()

will return true if the linetrace hits anything. It does not matter whether it hit an item or the wall or anything else.

Is that what you want this function to do?


So in essence - I want the linetracing
to stop if it registers a wall first.

You’re using a singlelinetrace, therefore it already returns the first hit =)

If you want this function to only return true once it hits an item, then somewhere you need to check what it is you’ve hit, cause right now you’re returning true if you hit anything.

My problem is that the function returns true when I hit the item even through a blocking object. I’ve set the wall to block everything there is to block. But it still goes through.

These are the collision settings for both the pickup and the wall… In the code, I am tracing for specifically the pickup type…

If you trace for Pickup object type, then it will only register a hit if it hits a Pickup object type and will ignore everything else. Since the wall is not of Pickup object type it will be ignored (it will behave as if the wall does not exist).

That’s what I am trying to fix. Is there a way?

Sounds good! I’ll try it as soon as I can! Thank you!

Alright, this works just as I would like it. Thank you for the idea. I don’t think I have the reputation to mark it as an answer, if you could, please do so.

You could do a linetrace by channel on top, so with the same start and end point (maybe create a new channel type and let the items and the wall block it). UWorld::LineTraceSingleByChannel | Unreal Engine Documentation

Then if both linetraces have hit the same object, then there was no wall in between (check if the hit actors are equal and make sure that they are not both nullptr). If there would be a wall in between, then the linetrace by channel will hit the wall and not the item.

Converted it to an answer =)