Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Physics.ComputePenetration when one object contains the other

Discussion in 'Physics' started by dgoyette, Nov 11, 2021.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,193
    I have a relatively simple bit of code that attempts to depenetrate a sphere from a surface via ComputePenetration. In general this works well, except in some cases where either the sphere is very small, or the other surface is moving rapidly. In those cases, I find it's typically for the sphere's center to be fully inside of the other collider, in which case ComputePenetration returns false and doesn't give me any results.

    Code (CSharp):
    1. Vector3 dir;
    2. float dist;
    3. if (Physics.ComputePenetration(OverlapCollider, effectiveCenter, this.transform.rotation, _overlapping[overlapIndex], _overlapping[overlapIndex].transform.position, _overlapping[overlapIndex].transform.rotation, out dir, out dist))
    4. {
    5.     var correctionAmount = Vector3.ClampMagnitude(dir * dist * Time.deltaTime * 50, dist);
    6.     //Debug.Log($"{Time.frameCount}: Currently overlapping {_overlapping[overlapIndex].gameObject.name} by {dist} in direction {dir} ({dir.magnitude}). Correction magnitude is {correctionAmount.magnitude}");
    7.     //Debug.DrawRay(effectiveCenter, correctionAmount, new Color(UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f), UnityEngine.Random.Range(0f, 1f)), 3f);
    8.  
    9.     totalCorrectionAmount += correctionAmount;
    10. }
    I looked into using Physics.ClosestPoint, but that also suffers from the same issue: If the sphere is inside the other collider, it just returns the sphere's center instead of a position on the collider.

    Does anyone have a suggestion on how to depenetrate a sphere from an object in cases where the sphere is fully contained within the object? The sphere should depenetrate itself along the shortest possible vector. (So just randomly moving in an arbitrary direction until it's no longer overlapping isn't really a good solution.)