# Unity - UI Raycast Hits Problem

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
Canvas
Canvas1
Canvas2
PlayMat (RectTransform with Canvas Renderer and holds the background image)
EventSystem
P1


## 2 Answers

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.

• Canvas objects can, in fact, react to raycasts. Image, for example, has a boolean to flag the canvas object for raycasting. – Gnemlock Dec 11 '16 at 6:44
• 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. – John Hamilton Dec 11 '16 at 6:45
• @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? – ljamison Dec 11 '16 at 6:53
• ahh, I see. It reads like "canvas - compatible objects", not "the Canvas object". Grammar makes everything ;) – Gnemlock Dec 11 '16 at 6:56
• Sorry, I had just woken up, didn't notice I had a mistake there. Thanks for the edits @Gnemlock :) – John Hamilton Dec 11 '16 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.