I'm having a hard time getting a UI to work and I'd love some advice on what I'm doing wrong.

I have a GameObject (P1 below) which holds a hand of cards (a script containing an array of GameObjects). Everything instantiates correctly from prefabs.

I followed this drag-and-drop example to create a draggable script applied to each prefab. Initially, I had the DropZone script from the tutorial video applied to the PlayMat object and had no problem (in tutorial video #2 it adds a Debug.Log message to the DropZone script to indicate when a successful drop has taken place.

Canvas1 and Canvas2 (same X scale as PlayMat but both are half the Y scale..imagine a card game field like Yu-Gi-Oh so Canvas1 is for Player 1 to place cards and Canvas2 is where Player 2 places cards) have coordinates that place them ABOVE the PlayMat but when I attempt a drop, only the PlayMat object registers. How can I make only Canvas1 or Canvas2 register the raycast hits?

Heirarchy as follows:

 Main Camera
     PlayMat (RectTransform with Canvas Renderer and holds the background image)

3 Answers 3


If I'm not mistaken, the default Canvas object does not have any colliders, and rays won't hit stuff with no colliders on them. Add a box collider component to the canvas, and if it still doesn't register, check the isTrigger bool on the box collider.

Also, rays might or might not hit UI layer, depending on the raycast function's parameters. If you want them to absolutely register the canvases, change their layer from UI to default.

Physics.Raycast: Casts a ray, from point origin, in direction direction, of length maxDistance, against all colliders in the scene.

  • \$\begingroup\$ Canvas objects can, in fact, react to raycasts. Image, for example, has a boolean to flag the canvas object for raycasting. \$\endgroup\$
    – Gnemlock
    Dec 11, 2016 at 6:44
  • \$\begingroup\$ Default canvas object, made from the right click > UI > canvas, has no image on it and no colliders. So they can't react to raycasts unless some other stuff are added on them. Also, from the way he tells it, he has two canvases that are essentially invisible (play fields) and he probably doesn't want images on them. \$\endgroup\$ Dec 11, 2016 at 6:45
  • \$\begingroup\$ @JohnHamilton is correct...I simply added the two Canvas for Player1 and Player2 because I needed a way for my scripts to determine where a card can be dragged/dropped based on the player (using gameobject.name). Unless someone can suggest a better/more efficient way? \$\endgroup\$
    – ljamison
    Dec 11, 2016 at 6:53
  • \$\begingroup\$ ahh, I see. It reads like "canvas - compatible objects", not "the Canvas object". Grammar makes everything ;) \$\endgroup\$
    – Gnemlock
    Dec 11, 2016 at 6:56
  • \$\begingroup\$ Sorry, I had just woken up, didn't notice I had a mistake there. Thanks for the edits @Gnemlock :) \$\endgroup\$ Dec 11, 2016 at 8:25

You can give them different layers and use a layermask.

Here is one example of letting a raycast only hit specific layers:

        //Ray from mouse to the underlying object
        Ray         ray         =   Camera.main.ScreenPointToRay(new Vector3(Input.mousePosition.x, Input.mousePosition.y, Camera.main.transform.localPosition.y / 2f));
        RaycastHit  raychit;
        //Ray should only collide with layer X (index of the layer)
        LayerMask   lymMask     =   1 << X;

        m_bCanvasHit = Physics.Raycast(ray, out raychit, Mathf.Infinity, lymMask);

X is the index of the layer in your Project Settings -> Tags and Layer. You can more layers which can be hit by the raycast by shifting more 1 into the layer mask, using other indices.


You need to add a GraphicsRaycaster to the canvases that you'd like to raycast onto.

As stated above, the physics raycast only hits colliders, so you need to use EventSystem.current.RaycastAll to hit your canvas.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .