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: 483
        
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].pointalong its hit normalRaycast down the negated hit normal for
float.MaxValue, onCollision.colliderIf 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