Here is a quick way, so you don’t need to attach a script on every world UI elements you have.
Add a new Layer, you can name it something like ‘World UI’
-On your World Canvas (the canvas having a world space render type), set its Layer to ‘World UI’ or the layer you just created.
attach this script on the world canvas or at any game object, empty or not
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class UIWorldDetect : MonoBehaviour {
void Update () {
RaycastWorldUI();
}
void RaycastWorldUI(){
if(Input.GetMouseButtonDown(0)){
PointerEventData pointerData = new PointerEventData(EventSystem.current);
pointerData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(pointerData, results);
if (results.Count > 0) {
//WorldUI is my layer name
if (results[0].gameObject.layer == LayerMask.NameToLayer("WorldUI")){
string dbg = "Root Element: {0}
Mark’s answer above didn’t work for me. I’m developing an AR/VR game and my primary use of UI raycasting is to detect whether the user (camera) is facing the canvas at a given frame.
I looked up the [Unity UI repository][1] and stripped out the part that’s doing the raycasting:
void Update()
{
IsFocused = false; // Member property... change this to whatever you want
Vector2 center = _camera.ViewportToScreenPoint(Vector2.one / 2); // Center of camera
var graphics = GraphicRegistry.GetGraphicsForCanvas(_canvas); // All Graphics in canvas
for (var i = 0; i < graphics.Count; i++)
{
var t = graphics*.rectTransform; // Get the Graphic's RectTransform*
Debug.Log($"name: {t.name}"); // Show their names if you want*
// Check if the RectTransform "contains" the center of camera == is "looked at" now*
IsFocused |= RectTransformUtility.RectangleContainsScreenPoint(t, center, _camera);*
}*
//Debug.Log(IsFocused); // Should be true if any Graphics were "looked at"*
}* …which works for me. IsFocused in the code above will be true if the camera is looking at one or more Graphic components in the canvas (i.e. Image, RawImage, Text, etc…) The key APIs in this code are - GraphicRegistry.GetGraphicsForCanvas() and - RectTransformUtility.RectangleContainsScreenPoint(). By using these functions properly you can check if your canvas “contains” any screen-space points in your camera. You can also apply these functions to the canvas itself’s RectTransform for better performance if your UI components will sit exactly within the canvas. Note that this code does not take account of objects occluding the canvas from the camera – the code wil always say “true” even if the canvas may be practically invisible from user. You’ll need to revisit the Unity UI repository above and see how the official API (is trying to) solve the situation if you need to test such occlusions. Hoping that this will help someone else. [1]: https://bitbucket.org/Unity-Technologies/ui/src/4f3cf8d16c1d8c6e681541a292855792e50b392e/UnityEngine.UI/UI/Core/GraphicRaycaster.cs?at=5.2&fileviewer=file-view-default