Search Unity

Question [3D] Help me make sense of Collision.GetContact().point. The returned value makes little sense.

Discussion in 'Physics' started by Mornedil, Nov 30, 2022.

  1. Mornedil

    Mornedil

    Joined:
    Feb 7, 2016
    Posts:
    22
    What value is retrieved with Collision.GetContact().point?
    I'm expecting the location the collision occurs at, but the position is way off.

    I did a test with a kinematic sphere with continuous collision detection, moving it at 10 units per second on the X axis towards a cube.

    When the cube has a rotation of (0,0,0), the contact point is located at exactly the surface of the cube where the sphere hits it.

    But when the cube is rotated, the contact point does weird things:

    Black line: Ball velocity
    White line: Line from ball's current position towards it's position before the collision
    Cyan line: Line from previous position towards Collision.GetContact(0).point

    The cyan line is nowhere near any point where the ball actually touched the cube. It's off to the edge where there shouldn't have been a collision.

    What am I doing wrong here?
    How can I get the position on the cube's surface where the sphere impacts it?


    Here's the code from my test:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class ContactTest : MonoBehaviour
    4. {
    5.     private Rigidbody RB;
    6.     private Vector3 NonCollisionPosition;
    7.     private Vector3 Velocity;
    8.     private bool CollidedThisFrame;
    9.  
    10.     void Start()
    11.     {
    12.         RB = GetComponent<Rigidbody>();
    13.         Velocity = new Vector3(10,0,0);
    14.     }
    15.  
    16.     private void OnCollisionEnter(Collision collision)
    17.     {
    18.         CollidedThisFrame = true;
    19.  
    20.         Debug.DrawLine(NonCollisionPosition, RB.position, Color.white);
    21.         Debug.DrawLine(NonCollisionPosition, collision.GetContact(0).point, Color.cyan);
    22.         Debug.Log("collision at time: " + Time.realtimeSinceStartup.ToString());
    23.     }
    24.  
    25.  
    26.     // Update is called once per frame
    27.     void FixedUpdate()
    28.     {
    29.         if(CollidedThisFrame)
    30.         {
    31.             Time.timeScale = 0f;
    32.             CollidedThisFrame = false;
    33.         }
    34.         else
    35.         {
    36.             NonCollisionPosition = RB.position;
    37.  
    38.             Debug.DrawRay(RB.position + Velocity * Time.fixedDeltaTime, Velocity * Time.fixedDeltaTime, Color.black);
    39.             RB.MovePosition(RB.position + Velocity * Time.fixedDeltaTime);
    40.            
    41.         }
    42.     }
    43. }
    44.