Facepunch / sbox-issues

162 stars 11 forks source link

Sphere vs Sphere collision callbacks return reversed speed #4605

Open youarereadingthis opened 5 months ago

youarereadingthis commented 5 months ago

Describe the bug

OnStartCollision is returning the wrong Contact.Speed when two spheres are involved. The direction is reversed.

To Reproduce

  1. Create a component with Component.ICollisionListener interface.
  2. Add a Gizmo.Draw representing collision.Contact.Speed at contact point.
  3. Give a GameObject the component and a sphere collider.
  4. Collide it with another sphere.

Expected behavior

Spheres against spheres should return the velocity you were going, instead of the reverse.

Media/Files

Gizmo.Draw.Color = Color.White;
Gizmo.Draw.SolidSphere( bouncePos, 4f );
Gizmo.Draw.Color = Gizmo.Colors.Red;
Gizmo.Draw.Line( bouncePos, bouncePos + speedNormal * 50f );

Additional context

No response

aylaylay commented 5 months ago

Speed and normal now get flipped for the other collider, see if that gives you what you want

youarereadingthis commented 5 months ago

I no longer have to make an exception for spheres in my bounce code. However there is another bug that I neglected to mention until now, because I'm cool like that.

Hit surface normals(Collision.Contact.Normal) are flipped for spheres when colliding against box colliders, mesh colliders, now sphere colliders(fixing one thing made it just as broken as the other things).

This is easily fixed by flipping them like the following code.

var surfNormal = c.Contact.Normal;

// Contact surface normals are fucked.
// if ( c.Other.Collider is not SphereCollider )
surfNormal *= -1;

Also, Contact.Speed seems to return really inconsistent values that are not appropriate for bouncing spheres. Contact.Speed will return wildly different values(like being reversed) depending on the size of the sphere, so I recommend different scales when debugging.

I fixed this by grabbing the last known velocity at the end of OnFixedUpdate instead and it works exactly as it should. I figure workarounds are worse than not needing them, though.