Maybe I’m just doing something wrong, but I’m unsure of what’s causing this issue.
I have a few, simple lines of code (lines 24 and 27) that are behaving differently on sloped surfaces depending on how far into the sloped surface my character is sitting.
[SerializeField] private LayerMask collisionMask;
private BoxCollider2D boxCollider;
private void Awake()
{
boxCollider = GetComponent<BoxCollider2D>();
}
private void Update()
{
DetectAndResolveCollision();
}
private void DetectAndResolveCollision()
{
// Get the collision/overlap
Collider2D collision = Physics2D.OverlapBox(transform.position, boxCollider.size, 0, collisionMask);
// Get the collision distance info
ColliderDistance2D colliderDistance = collision.Distance(boxCollider);
// Find the shortest resolution vector
Vector2 resolutionVector = Mathf.Abs(colliderDistance.distance) * colliderDistance.normal;
// Resolve the collision by moving out of it by the shortest amount
transform.Translate(resolutionVector);
}
I’ve already discovered a superficial reason for my problem that will hopefully be better explained by this picture:
What I’ve noticed is that if only one corner of the character’s collider is in the slope, the resolution occurs as expected (as shown in the top half of the picture). However, if more than one corner of the character’s collider is in the slope, the shortest resolution is defined as the distances from the center of some side/face of the box collider to its closest point on the outside of the slope. Therefore, if 3 corners are in the slope, the distance from the center of two sides/faces of the box collider to their closest points outside the slope will be compared, and the shorter distance will be used in the “resolution” by pushing this center point out of the slope. The problem, of course, is that the entire collider is not pushed out of the collision when this happens, so I would have to run the collision check a second time, which seems like an incorrect approach.
Why is this happening? I thought ColliderDistance2D
- and, more specifically, Collider2D.Distance
, which returns a ColliderDistance2D
object - was always supposed to give you the shortest distance that moves the ENTIRE collider out of its collision. The Unity docs even say that Collider2D.Distance
“calculates the minimum separation of this collider against another collider.” How can the “minimum separation” be a value that doesn’t fully separate the colliders?
I’ve already been using trigonometry to figure out a lot of different ways to resolve collisions, and I know I can do that here too, but I was hoping to overcome this discrepancy with a built-in solution that already exists in Unity. I would appreciate any help or explanations that can be offered.