Search code examples
c#unity-game-enginecollision-detectioncollisionraycasting

Place an object where Raycast points but taking collisions into account in Unity3D


I am trying to place an object where my Raycast points (where the Raycast finds a collision). But what I get is what you see in the image attached (2 different cases). The object is placed where I am pointing indeed, but I would like to take the collisions into account so that the objects do not go through each other. Every object has its own Collider.

Two different cases in which objects are positioned through each other

Does anybody know how to solve this? Thank you.

Jan

EDIT:

I have tried to implement the solution given by @31eee384 like this:

RaycastHit hit;
Game.MuebleAEditarGO.transform.position = CameraFacing.transform.position;
if (Game.MuebleAEditarGO.GetComponentInChildren<Rigidbody>().SweepTest(CameraFacing.transform.rotation * Vector3.forward, out hit, 50f))
{
    Game.MuebleAEditarGO.transform.position += CameraFacing.transform.forward * hit.distance;
}

MuebleAEditarGO is a RigidBody. The walls (and the house in general) are not rigidbodies and they have MeshoColliders each.

But then I get a solution that partially works. It appears to be working fine when the RaycastHit finds only one collision (see the image below).

Image showing the problem with rigidbodies and collisions


Solution

  • The most direct solution is one that uses Unity's physics engine: Rigidbody.SweepTest. It sweeps your actual rigidbody with its colliders (no abstraction like a bounding box or manual distance checking), and it will do so with all the optimization and generalized calculations a physics engine can offer.

    To use it, check the example on the doc page for SweepTest, copied here for completeness:

    RaycastHit hit;
    if (rb.SweepTest(transform.forward, out hit, collisionCheckDistance))
    {
        aboutToCollide = true;
        distanceToCollision = hit.distance;
    }
    

    Then use transform.forward * distanceToCollision to determine how far to move the object until it makes its first collision. For example:

    RaycastHit hit;
    couch.transform.position = transform.position;
    if (couch.SweepTest(transform.forward, out hit, 50f))
    {
        couch.transform.position += transform.forward * hit.distance;
    }
    

    Make sure that your objects are on different physics layers so the couch doesn't collide with the player's collider(s).