Why doesn't Unity's OnCollisionEnter give me surface normals, and what's the most reliable way to get them?
Posted
by
michael.bartnett
on Game Development
See other posts from Game Development
or by michael.bartnett
Published on 2012-10-16T05:50:44Z
Indexed on
2012/10/16
11:25 UTC
Read the original article
Hit count: 410
Unity's on collision event gives you a Collision object that gives you some information about the collision that happened (including a list of ContactPoints with hit normals).
But what you don't get is surface normals for the collider that you hit. Here's a screenshot to illustrate. The red line is from ContactPoint.normal
and the blue line is from RaycastHit.normal
.
Is this an instance of Unity hiding information to provide a simplified API? Or do standard 3D realtime collision detection techniques just not collect this information?
And for the second part of the question, what's a surefire and relatively efficient way to get a surface normal for a collision?
I know that raycasting gives you surface normals, but it seems I need to do several raycasts to accomplish this for all scenarios (maybe a contact point/normal combination misses the collider on the first cast, or maybe you need to do some average of all the contact points' normals to get the best result).
My current method:
Back up the
Collision.contacts[0].point
along its hit normalRaycast down the negated hit normal for
float.MaxValue
, onCollision.collider
If that fails, repeat steps 1 and 2 with the non-negated normal
If that fails, try steps 1 to 3 with
Collision.contacts[1]
Repeat 4 until successful or until all contact points exhausted.
Give up, return
Vector3.zero
.
This seems to catch everything, but all those raycasts make me queasy, and I'm not sure how to test that this works for enough cases. Is there a better way?
© Game Development or respective owner