Inaccuracy in distance given by Ridgidbody2D.Cast?

I’m trying to move a 2D physics object using Ridgidbody2D.Cast. When a collision is detected, the distance given by the RaycastHit2D seems incorrect because the collider never ends up flush with the collider that was hit.

I’ve made a sample project. If you hit play and watch both colliders in the scene view of the editor, you can see that the CircleCollider2D of the falling “ball” object goes a little ways into the BoxCollider2D of the “Quad” object.

https://github.com/drewgingerich/Raycast2D-Overshoot-Test

Here’s the script that handles movement:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Rigidbody2D))]
[RequireComponent(typeof(Collider2D))]
public class Actor : MonoBehaviour {

    [SerializeField]
    private Collider2D otherCollider;

    private Rigidbody2D rb2d;
    private Collider2D collider;
    private RaycastHit2D[] hitBuffer = new RaycastHit2D[8];
    private ContactFilter2D contactFilter;
   
    void Awake() {
        rb2d = GetComponent<Rigidbody2D>();
        collider = GetComponent<Collider2D>();

        contactFilter = new ContactFilter2D();
        contactFilter.useTriggers = false;
        contactFilter.SetLayerMask(Physics2D.GetLayerCollisionMask(gameObject.layer));
    }

    public void Move(Vector2 move) {
        float distance = move.magnitude;
        Vector2 direction = move.normalized;
        float searchDistance = distance;

        int count = rb2d.Cast(direction, hitBuffer, searchDistance);
        if (count > 0) {
            distance = hitBuffer[0].distance;
        }

        // transform.Translate((Vector3)direction * distance);
        rb2d.MovePosition(rb2d.position + direction * distance);

        ColliderDistance2D colDistance = collider.Distance(otherCollider);
        Debug.Log(string.Format("Cast distance: {0}, Overlap distance: {1}", distance, colDistance.distance));
    }
}

And here’s the script that causes downward movement using the above script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(Actor))]
public class SimpleBallController : MonoBehaviour {

    private Actor actor;

    void Awake() {
        actor = GetComponent<Actor>();
    }

    void FixedUpdate() {
        actor.Move(Vector2.down * Time.fixedDeltaTime);
    }
}
1 Like

Hmm, that is very odd. I’ll take a look for you in a little while.

Thank you! I also posted this question to Unity Answers here. I have not received any solutions and I’ll try to keep the information in parallel, but I figure it’s good to have everything in plain view. And I’ll do my best to provide more information if you need it!

I can see the answers you were provided but they are not exactly correct. It seems there is indeed a bug with circle vs anything else in that it slightly overshoots by the contact offset. This is most certainly a bug.

Is there any chance you could provide a bug report I can fix this against? Do not worry if not but it would certainly help verification.

I just submitted a bug report: case 1098169. Thanks!

Thanks, I have the case and will look at.

1 Like

Hey there, any word on this issue? Should I just be waiting to get an email update about the bug report? It’s kinda stalled my project since it seems so fundamental to the type of character controller I’m trying to make. Again, thanks for your help!