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);
}
}