0
\$\begingroup\$

I have converted my project to URP and suddenly I found the situation where my Raycast code even is working beneath the collider (other layer colliders):

if (DisplayMessage.Click && Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 1000f, layermask))

I corss check the signature of raycast it is fine and the collider it self. Is there any changes in URP? Here is the way i am setting the layer:

int layermask => LayerMask.GetMask("Interact");

Scenario: In my scene, I have a plane (Default Layer) and a cube(Interact layer). The cube is beneath the Plane. But my camera Detecting the cube on mouse pointer and bypassing the Floor. The raycast should acctually not work if there any object of the desired layer.

\$\endgroup\$
4
  • \$\begingroup\$ How have you configured your layermask variable? Is it set to ignore the plane and fire through it? \$\endgroup\$
    – DMGregory
    Mar 18 at 12:14
  • \$\begingroup\$ int layermask => LayerMask.GetMask("Interact"); \$\endgroup\$ Mar 18 at 12:15
  • 1
    \$\begingroup\$ So you told your raycast "please pretend that anything on the Default layer isn't there" and now you're wondering why it's not affected by a plane on the Default layer? 😉 \$\endgroup\$
    – DMGregory
    Mar 18 at 12:17
  • \$\begingroup\$ Oh! silly me. Even after spending much time I am unaware about how to raycast \$\endgroup\$ Mar 18 at 12:19
1
\$\begingroup\$

This is unrelated to URP. That's part of the rendering system, while raycasts are handled by the physics system, and it's the same physics system no matter what renderer you use.

When you give a layer mask to a raycast, you are asking it to consider colliders only on the layers enabled in the mask. Any other layers are ignored - the raycast behaves as though those colliders were deleted from your scene.

So if you want to cast a ray, then check if it hit the layer of your choice (and not an intervening collider on a different layer), you can do it like so:

if (DisplayMessage.Click 
    && Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 1000f)
    && hit.collider.gameObject.layer == interactionLayer) {
    // Do a thing.
}

Here we include all layers in our raycast, so obstacles on other layers can block it. Then, once we've hit something, we check whether it's the layer we wanted to hit. If not (ie. we hit an obstacle on a different layer), then we fail out of the if. Only if we hit our desired layer with no obstacles in between do we enter the body of the if.

\$\endgroup\$
4
  • \$\begingroup\$ The code works fine with a modification instead LayerMask.GetMask("Interact"); i am using LayerMask.NameToLayer("Interact"); . I don't know why getMask was returning 512. \$\endgroup\$ Mar 19 at 5:25
  • \$\begingroup\$ We have to Raycast all the time? isn't performance inefficient. \$\endgroup\$ Mar 19 at 5:26
  • \$\begingroup\$ A layer mask is a different thing than a layer. It's a bitmask that can select/reject multiple layers. So if your interaction layer is layer #9, a bitmask containing that layer will have its 10th bit set (starting from 0): 2^9 == 512. Note that my code example asks for a layer, not a mask. A few raycasts each frame won't break the bank, but if your profiling shows a major cost then you can post a new question asking for ways to improve the performance. \$\endgroup\$
    – DMGregory
    Mar 19 at 11:05
  • \$\begingroup\$ @MuhammadFaizanKhan Regarding the performance concerns: Yes, too many raycasts per frame can cost you performance. But you are performing one raycast per click. Which is once per frame at most. I wouldn't worry about the costs of raycasts unless you are performing several hundred per frame. \$\endgroup\$
    – Philipp
    Apr 19 at 12:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.