Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Capsule collider generates predictably wrong collision detection on terrain

Discussion in 'Physics' started by PurpleGoop, Feb 16, 2022.

  1. PurpleGoop

    PurpleGoop

    Joined:
    Apr 30, 2018
    Posts:
    15
    Hi folks,
    i was in the process of making my own custom character controller, with no rigidbody required.
    I made a custom collision detection script that is basically just a "conputePenetration" function with a "checkSphere" to get the colliders it should depenetrate from, very basic.
    The problem arises when the collider (a capsule) collides with a terrain OR any other mesh collider that is similar to a terrain (meaning a subdivided surface with some bumps on it). The capsule basically falls through the edges of the terrain for 1 or two frames, then detects collision again and goes back to behaving normally.
    I tested it with a sphere, side to side with the capsule, exact same script, and it perfectly slides down the hill, no bumps. After spending some time trying to find an answer by testing and by searching on forums, it now seems to me that its just some limitation with the capsule collider itself.
    Here is a demonstration of the problem, the white lines that are being cast represent the direction * distance produced by the computePenetration function:

    You can see how the capsule bumps every time it slides past the edge of the terrain's faces, while the sphere only has that little bump (actually first time i saw that happen myself), but its not even noticeable without the debug lines.
    I can see a pattern, but i dont understand why the sphere isnt affected.
    Heres the code (some things are badly coded just for the sake of debugging):
    Code (CSharp):
    1. public class DebugCollison : MonoBehaviour
    2. {
    3.     [SerializeField] float height = 1;
    4.     [SerializeField] float radius = 0.5f;
    5.     [SerializeField] float center = 0f;
    6.     [SerializeField] int maxColliders = 5;
    7.     Collider[] hitColliders;
    8.     Collider charCollider;
    9.     Vector3 direction;
    10.     float distance;
    11.     float fall;
    12.  
    13.     private void Awake()
    14.     {
    15.       charCollider = GetComponent<Collider>();
    16.       hitColliders = new Collider[maxColliders];
    17.       charCollider.contactOffset = 0.01f;
    18.     }
    19.  
    20.     Vector3 VectorBuilder(float h)
    21.     {
    22.       return transform.position + transform.up * h;
    23.     }
    24.  
    25.     void ComputeCollisions()
    26.     {
    27.       bool overlap = false;
    28.       int count = Physics.OverlapCapsuleNonAlloc(
    29.           VectorBuilder(height + center),
    30.           VectorBuilder(-height + center),
    31.           radius, hitColliders, ~0);
    32.  
    33.       for ( int i = 0; i < count; i++) {
    34.         if (hitColliders[i] == charCollider)
    35.           continue;
    36.         overlap = Physics.ComputePenetration (charCollider, transform.position, transform.rotation,
    37.            hitColliders[i], hitColliders[i].transform.position, hitColliders[i].transform.rotation,
    38.            out direction, out distance);
    39.         if (overlap)
    40.         {
    41.           transform.position += direction * distance;
    42.           fall = 0;
    43.         }
    44.       }
    45.       Debug.DrawRay(transform.position - transform.up * 0.5f, direction * distance, Color.white, 5);
    46.     }
    47.  
    48.     void FixedUpdate()
    49.     {
    50.       fall += Physics.gravity.y * Time.deltaTime;
    51.       transform.position += transform.up * fall * Time.deltaTime;
    52.     }
    53.  
    54.     void Update()
    55.     {
    56.       ComputeCollisions();
    57.     }

    Known issue?

    Thanks in advance.
     
  2. r31o

    r31o

    Joined:
    Jul 29, 2021
    Posts:
    460
    Is a requirment to dont use a rigidbody or character controller?

    I dont know what is happening, I guess the capsule kinda enters down the terrain. Make more checkings.
     
  3. PurpleGoop

    PurpleGoop

    Joined:
    Apr 30, 2018
    Posts:
    15
    hi r31o,
    Im making this so that the controller is my own. For the rigidbody part, i do have one but its kinematic and locked in rotation and location, so its basically just there to interact with other objects, but not used by the script itself.
    Idk if its straight up stupid to make a CC without unity's rigidbody.
    Btw, i further modified the script, and now it applies no gravity when grounded, and moves based on a crossProduct of the raycastHit.normal (a raycast pointing forward, or if it fails, one that goes straight down, so that it can move up and down slopes aswell )and directionVector (the vector that dictates the movement direction), so i dont have this problem anymore, but i didnt fix it, i just bypassed it.
     
  4. r31o

    r31o

    Joined:
    Jul 29, 2021
    Posts:
    460
    Why you dont try to use the built in character controller and add a script to make it interact with physics objects?
     
  5. PurpleGoop

    PurpleGoop

    Joined:
    Apr 30, 2018
    Posts:
    15
    i already did, and for what im trying to do it actually made it more complicated as i wanted more control over the behavior of the controller itself, but i might just be inexperienced:(. Either way i ended up wanting to use a custom one, and besides this topic isnt really about the controller as much as it is about the capsule collider acting weird .
     
  6. r31o

    r31o

    Joined:
    Jul 29, 2021
    Posts:
    460
    I know that combining charcter controller and rigidbody makes the object fly (personal experience), but what about character controler and kinematic rigidbody?
     
  7. PurpleGoop

    PurpleGoop

    Joined:
    Apr 30, 2018
    Posts:
    15
    thing is i have already tried the kinematic rigidbody way using OnCollisionEnter, and the capsule still falls through the edges o_O. Whether i use a rigidbody or not doesnt seem to matter