I am just using the plane mesh for now. I am using ApplyLinearImpulse to move a ball (sphere shape) forward. With the mesh collider on my plane, the ball hits the inner edges and bounces up a little. I have set Restitution to 0 for both Physics Shapes, and it’s minimal but still noticeable. I also have linear damping set to 0 as I want my ball to free roll.
It appears as if it’s hitting the edges. Almost as if for a moment in between faces, it drops down due to gravity for a fraction and gets knocked up again. problem worsens with velocity.
Anyone know why this could be happening, and even better a solution?
This problem is due to speculative contacts created from Unity Physics’ approach to continuous collision detection.
See the Speculative CCD section here (Unity - Manual: Continuous collision detection (CCD)) for equivalent information from the land of GameObjects.
I think I understand the issue well now.
The collision detection in Unity.Physics uses a continuous approach, it ‘looks ahead’ a fraction to detect a future collision and keeps the velocity the same until then. When traversing between two different triangles, it will look ahead and get the next triangle, then get the contact point. This contact point will be the edge, and is used to calculate the physics from. Because the edge has a normal direction perpendicular to face normal, the physics is calculated from this edge normal. Thus causes a little change in velocity which is seen as my ball ‘bumping’ over the joins.
Not sure I got this right. I was expecting normals for edges to be -forward, and surface to be up.
A normal detected before a ‘bump’ was float3(0f, 0.9456903f, -0.3250691f). So perhaps it’s a computed normal. I went ahead and set to the surface normal (in my case up - just testing flat mesh) and no change.
I am using code written base on the example on so far it’s just to test, but in my ModifyNormalsJob I have this instead:
if ((contactHeader.Entities.EntityA.Equals(TargetEntity)
|| contactHeader.Entities.EntityB.Equals(TargetEntity))
&& contactHeader.Normal.y< 0.9999f)
{
UnityEngine.Debug.Log(
$"Not Normal {contactPoint.Index}: {contactHeader.Normal}"+
$"Distance: { contactPoint.Distance}\n"+
$"PositionA: {math.round(contactPoint.Position * 10000)/ 10000}");
var newNormal = new float3(0, 1, 0);
var distanceScale = math.dot(newNormal, contactHeader.Normal);
contactHeader.Normal = newNormal;
contactPoint.Distance *= distanceScale;
}
With example output:
Now, I tested with a box shape with 0 Bevel, and 0 friction. And it smoothly transitions across the edges, unlike before this script where it would tumble.
Also went back to sphere shape, with 0 friction and bingo, it is smooth. However, If I add friction so it rolls, I get the bumping back again.
So now we’re having an issue with only rolling across these edges. Sliding is fine.
Hello, do you know how to go about finding the appropriate face normal for any given contact data? I’ve looked into that myself and was unable to figure it out.
I didn’t get that far, but I had a quick look and couldn’t see how, my best guess was going to raycast a bit further forward in the direction of movement, but then that isn’t available either. so have to pass in list of PhysicVelocity Components and their respective entities to look up from the entity pair, and that’s just to get the velocity. Next have to raycast, so need to pass in the PhysicsWorld. IMO this might be too much processing to be done here for anthing but a small scale simulation.
Yeah, it’s a tricky problem. I was hoping steveeHavok might have more information about how to go about doing it. I’ve actually posted about this recently without much success Rolling Ball Bounces On Mesh Edges