Why does my raycast not register a hit or initial overlap? On surface of a mesh inwards


I’ve been having a problem with raytracing that I’m hoping someone might know more about.

For a game mechanic, I am raycasting from a point in a rope to a point on the line between the points before and after it (as demonstrated in the below image), to check if the point in the rope should move away from an actor it has attached to. I have set up debug lines and spheres to visualize this:

(the lines are green when the point should move, and red if it should not, and the point it is raycasting to is the gold sphere)

However, it seems that because the points are created on the surface of actors (they are generated through raycasting between two points to determine if there is a collision), raycasting will not work consistently, shown by the lines being green when they should be red:


(you’ll notice the end point of the trace is inside of the actor)

My code for the method to check this is as follows:

bool ASilkPoint::CheckMove(FVector movePointLoc, float desiredFreeDistance)
     // Perform trace to retrieve hit info
     FCollisionQueryParams TraceParams(FName(TEXT("RibbonTrace")), true, this);
     TraceParams.bTraceAsyncScene = false;
     TraceParams.bReturnPhysicalMaterial = true;
     TraceParams.bFindInitialOverlaps = true;
     TraceParams.bTraceComplex = true;
     FHitResult Hit(ForceInit);
     FVector StartTrace = GetActorLocation();
     FVector EndTrace = movePointLoc;
     GetWorld()->LineTraceSingleByChannel(Hit, StartTrace, EndTrace, COLLISION_SILK, TraceParams);
     float distance = FVector::Dist(Hit.TraceStart, Hit.Location);
     if ((Hit.bBlockingHit && (distance <= desiredFreeDistance)))
         DrawDebugLine(GetWorld(), StartTrace, EndTrace, FColor(255, 0, 0), false, -1, 0, 12.333);
             return false;
     else if (Hit.bStartPenetrating && Hit.PenetrationDepth > FVector::Dist(StartTrace, EndTrace))
         DrawDebugLine(GetWorld(), StartTrace, EndTrace, FColor(0, 0, 255), false, -1, 0, 12.333);
         UE_LOG(LogTemp, Warning, TEXT("Penetrating!!!!"));
         return false;
     else if (Hit.bStartPenetrating)
         return false;
     else if (Hit.bBlockingHit)
         return false;
         DrawDebugLine(GetWorld(),StartTrace,EndTrace,FColor(0, 255, 0),false, -1, 0,12.333);
         return true;

The third and fourth else if statements were put in merely to see if the raytrace was registering any hit at all or if it registered that it started inside of the object. If the method returns false, then the method that calls this one will draw red lines instead of green. Also, COLLISION_SILK is defined as ECC_MAX, as i wanted to eliminate the possibility of the problem being my trace channel, before i reduce it to another, less performance-heavy channel.

Anyone have any ideas on why this doesn’t work?

Thanks in advance!!

P.S. What is a better forum to post to for questions like these? I have posted questions on UE4 Answerhub in the past and posted this one to both there and here.

I think this forum is appropriate and has the most relevant viewers. For your problem, I believe tracing ECC_MAX does not mean all channels are traced. Rather its just to denote the last valid channel index.

I would try rechecking all this:

  • Choose a specific channel to trace on
  • Make the meshes block and overlap that channel
  • Although you’re using single trace, I recall that when using multi trace the function returns true only if the trace had a blocking hit. With multi trace, it can return false and still have overlap hit results. Maybe single trace does the same, I’m not sure but try checking the hit result even if it returns false.

Hope this helps you.

Edit: Sorry I see you are checking bBlockingHit and bStartPenetrating instead of the return value of trace so a false expectation of the return value isn’t the issue. I’m not sure if bStartPenetrating is used to denote an overlapping hit with line traces. You can always check the HitActor to make sure. Maybe narrow down the issue by checking only bBlockingHit or bStartPenetrating hit first, drawing a red line then and after that do your extra checks like for penetration depth.

Probably no collision on objects??? Maybe…