Search code examples
c#unity-game-enginegame-developmentraycasting

Raycast doesn't hit UI objects


I have the following problem:

I have a scrollview that is populated with Panels. Now I want to be able to rightclick between two panels and create another panel at that position. All the panels are saved in a list.

My idea was to have a cursor Object that follows my mouse and sends a Raycast above and below the cursor. This way, I would know what the previous or following panel should be, so I can insert the new panel at the right position in the list. Rough drawing of my project

But the problem is that my Raycast doesn't register any contacts.

All the panels have a Boxcollider 2D, the Layermask is set to Everything (also tried with only UI). I am sure it must be a stupid mistake that I am just overlooking, but I just can't find it. Also my

Debug.DrawRay

function doesn't work either (Gizmos are turned on).

public class Mouse : MonoBehaviour
{
    public LayerMask mask;

    void Start()
    {
    }

    void FixedUpdate()
    {
        Vector3 pos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0);
        transform.position = Camera.main.ScreenToWorldPoint(pos);


        RaycastHit2D hitup = Physics2D.Raycast(pos, Vector2.up, 10, mask);
        Debug.DrawRay(pos, Vector2.up * 3, Color.green);
        RaycastHit2D hitdown = Physics2D.Raycast(pos, Vector2.down, 10, mask);
        Debug.DrawRay(pos, Vector2.down * 3, Color.green);


        if (hitup)
        {
            Debug.Log("Hit something above");
            Debug.Log(hitup.collider.gameObject.name);
        }
        else if (hitdown)
        {
            Debug.Log("Hit something below");
            Debug.Log(hitdown.collider.gameObject.name);
        }

    }
}

This ist the Mouse Script attached to the mouse Object.

I thought that maybe it's because the mouse Object in Unity is on -10 on the z-Axis but the UI elements are on z = 0, so I tried to set z to 0, but that doesn't work either for some reason, it keeps resetting to -10.

Though I may not answer instantly because I'm going to go to bed now, all help is really appreciated, thank you.


Solution

  • For starters, using physics for UI is a horribly unoptimal approach. Leave that overhead for your game physics rather.

    The physics system also uses world co-ordinates and you're also converting the mouse postition to world co-ords so its not that debug raycasts are not working, its that the rays are being cast at some arbitrary point in the world.

    You should instead be using the GraphicsRaycaster component which is designed to cast rays onto UI elements like the Image component which will natuarlly be on your panels.

    Lastly, it is super unreliable and still unoptimal to cast rays out from the mouse to find the nearest panels.

    Here's a proposed better solution:

    When the user clicks on the space between two panels, loop through the panels and compare their Y positions to the mouse Y position (for vertical layouts) and obviously this way you can determine which panels are right above and below the cursor.

    Hope this helps.