When I use OnComponentBeginOverlap event in blueprint, the event fires appropriately, but when I try to break the sweep result with break hit, all of the values are 0. I’m trying to find the impact normal of two actors overlapping but I don’t want them to actually collide with one another so I thought overlapAll and bgeneratesoverlapevents would be the ticket. Is there something I need to do to get this event to generate the expected result? Should I take another approach?
I have the same question. I use c++, and a collisionbox primitive is checked against a capsule for example. Event fires, but the SweepResults is empty.
Any idea how to get more detail on the collision?
I would like to have the world coordinates of the point of intersection.
add me to the people looking forward to an answer for this question
I have also stumbled against this issue and i have no idea if i’m doing something wrong or it’s a bug
I would also like to know how to make this work.
Unfortunately the onOverlap events are not able to output any collision information.
There is a work around solution but is quite a hack: You can use onHit events and disable the contact forces generated in physX. Therefore you get the FHitResult (contact normals, contact points etc), while the objects overlap.
As you can probably tell this can only be achieved in C++. You also have to alter the engine’s source files. What’s awesome is that UE4 is truly open! The sky is the limit! and the time of course ;). If you can afford to dig that deep look at collision filtering and contact modification in physX: https://developer.nvidia.com/sites/default/files/akamai/physx/Manual/Callbacks.html
I’d do a line trace on the overlap to both my actors and break off the hit event from there
How do you determine the two ends (or the start and direction) of the trace?
I’m having the same problem and worked around it by doing a spherical sweep when I get the overlap event. This seems to work for me, but I also use a spherical collision hull. Here is my code, slightly simplified to be more generic:
void AMyPawn::OnComponentBeginOverlap(class AActor* OtherActor, class UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (OtherActor && (OtherActor != this))
{
TArray<FHitResult> AllResults;
// Get the location of this actor
auto Start = GetActorLocation();
// Get the location of the other component
auto End = OtherComp->GetComponentLocation();
// Use a slightly larger radius to ensure we find the same result
auto CollisionRadius = FVector::Dist(Start, End) * 1.1f;
// Now do a spherical sweep to find the overlap
GetWorld()->SweepMultiByObjectType(
AllResults,
Start,
End,
FQuat::Identity,
0,
FCollisionShape::MakeSphere(CollisionRadius),
FCollisionQueryParams::FCollisionQueryParams(false)
);
// Finally check which hit result is the one from this event
for (auto HitResult : AllResults)
{
if (OtherComp->GetUniqueID() == HitResult.GetComponent()->GetUniqueID()) {
// A component with the same UniqueID means we found our overlap!
// Do your stuff here, using info from 'HitResult'
OnComponentBeginOverlapWithInfo(OtherActor, OtherComp, OtherBodyIndex, bFromSweep, HitResult);
break;
}
}
}
}
This solution sucks, but it’s the best I could come up with. You could probably still tweak it a bit with the parameters of SweepMultiByObjectType
. In particular I suspect FCollisionObjectQueryParams
and FCollisionQueryParams
could be used to reduce the search space.
I hope this will help someone, somehow but it would be great to hear a better solution!
Well in my case, the start point is the center of my ‘player’ and the direction would be in the actual velocity direction. Or in my case which ever direction the player happens to be aimed at.
I’m using the same attempt, but I feel like the Trace happens few frames after the overlap, making it unreliable. Though that might be cause I’m using it with an animation.
Yeah, I also got the impression it’s not super reliable. I didn’t investigate it much though and it might be that I just did something wrong while testing. Anyhow, I worked around that by making the radius 10% bigger:
auto CollisionRadius = FVector::Dist(Start, End) * 1.1f;
Some quick testing gave me the impression that it works for my use case.
But doesn’t that give you quite a big error, depending on which velocity (angle) an object has when it overlaps? Or even worse; that the line trace could completely miss the object, if you hit it on an edge. And also, isn’t the impact normal then always equal to the velocity (just in the other direction)? Here a picture that hopefully clarifies a bit what I mean:
Sorry if these are stupid questions, but I’m still new to UE4. I guess the performance of a line trace would be much better than the sweep I do, I just wonder if it really works for a more generic use case.
Ok yeah, I think you’re right there. I misspoke so let me clarify what’s going on. After reviewing my situation may be a little different than yours. First I should say my end goal here was to play a sound to represent the impact noise. So all I needed to figure out was the impact velocity.
So it turns out I’m using the hit event, and then I’m getting the hit location, and I’m doing a trace from the center of my actor to the hit location. Then I grab the linear velocity and multiply it by the impact normal (to get the impact velocity) and do a calculation to determine how loud that sound should play. It works well. Except for when you are moving up or down hill, for some reason hit events fire while moving on a slanted surface.
Thanks for the clarification!
Here is a quick and dirty blueprint solution for a spherical trigger:
(EDIT: Actually it should work for any trigger shape as long as the sphere trace encompasses it.)
First we make sure that although multiple overlap events can fire per actor per frame, we work with each actor only once:
(Part of the node network to the right is omitted for brevity.)
Then we pick an arbitrary point which is definitely outside the detection sphere. That is our starting nearest detected point, used in comparisons later, to find the closest point on the actor at hand.
The next step is firing a very very short sphere trace. Zero length (actual sphere) doesn’t work so we make it 1 cm long which is spherical enough. This spherical trace now covers the trigger sphere and returns all hits inside.
Let’s go through the hit results in a “for each” loop. The loop body starts like this:
Two things to note here: First, since we started this whole process after an overlap event occurred, we can be sure that the current actor is (partially) inside the sphere so it will be initially overlapping with the sphere trace as well. When that happens then some hit result properties change their meaning. For example “Normal” then stores the depenetration vector, a direction from the center of the sphere pointing toward one of the nearby points on the current actor. I have no idea how those points are picked I just saw that they are close and they are many.
Which brings me to the second important note: Multiple hit results will be about the same actor, containing a different one of those “nearby” points. So if we want to be as precise as possible then we can not break from the foreach loop when we found our actor the first time: we will have to check all hits and pick the closest of the nearby points.
Since so far we only have a direction of such a point we do a line trace in that direction to see how far our actor actually is. We iterate through the trace hits:
If we found the actor in question then we see if the hit point is the new nearest or not. And in any case we break out from the loop since the rest of the hits are irrelevant. After that we carry on iterating through the sphere trace’s hit results and doing this same line trace every time the current actor shows up. When we are done we should have the closest of the available points.
This method is not very precise, especially when the actors involved are moving fast, but might be good enough until we get a more elegant native solution.
Is this ever going to be fixed?
Another solution that might not work for all cases, Make a socket in the component you are calling the on overlap event and at the moment of hit you have the location of the socket, Useful for spawning impact emitters for combat events
Hey everyone,
I just tested this in 4.10.2 and the Normal and Impact Normal now output the correct values. However, I’m not sure that it is outputting the exact information that everyone here is expecting but I believe it is outputting what the OP (Parakeet) was originally asking for.
Parakeet: Please give it a try if you like and let me know if you were expecting different results and why.
Cheers,
TJ
I can’t confirm this. At least not in C++. I migrated my 4.9.2 project to 4.10.2 just for that reason.
This is the collision setup for the hitbox of my weapon:
And this for my character’s capsule component:
Hit event is fired. But no matter what, SweepResult.ImpactPoint
, SweepResult.ImpactNormal
, SweepResult.Location
, SweepResult.Normal
are all FVector( 0.f, 0.f, 0.f )
.