Use GraphicRaycaster in Editor Mode

I would like to do a right click and be able to log every UI hit.

I have this class but seems not to be raycasting, or the pointer event data is wrong.

In the scene view i have a canvas with and Image and inside of it a Button.

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[InitializeOnLoad]
public class RightClick : Editor{
    static GraphicRaycaster raycaster;
    static PointerEventData pointerEventData;
    static EventSystem eventSystem;

    static RightClick(){
        SceneView.onSceneGUIDelegate += OnSceneGUI;
    }

    static void OnSceneGUI(SceneView sceneview){
        if (Event.current.button == 1) {
            if (Event.current.type == EventType.MouseDown) {
                raycaster = FindObjectOfType<GraphicRaycaster>();
                eventSystem = FindObjectOfType<EventSystem>();
                pointerEventData = new PointerEventData(eventSystem) { position = Event.current.mousePosition};

                List<RaycastResult> results = new List<RaycastResult>();
                raycaster.Raycast(pointerEventData, results);

                foreach (RaycastResult result in results) {
                    Debug.Log("Hit: " + result.gameObject.name);
                }
            }
        }
    }
}

It’s similar to the script provided in the doc, but I need it working in editor

https://docs.unity3d.com/ScriptReference/UI.GraphicRaycaster.Raycast.html

Hi Martin! Did you ever figure this out? Trying to achieve the same thing. :slight_smile:

Nope :frowning:

Did some more tests, it seems that

  1. The Raycast methods only work in play mode
  2. The coordinate conversions are tricky to get right

There must be a way, I want to throw a raycast and get all UIs I’ve hit

I had a bit of luck in getting it to work, but…

  1. It only works in 2D mode & orthographic directly from the front.
  2. It requires that the canvas is set to Screen Space - Camera, and that a render camera is set.
  3. It requires raycastTarget to be enabled on the UI elements in order to detect them (might be obvious, but if it’s a requirement to hit all the UI, this approach won’t work)

Vector3 screenPosition = Event.current.mousePosition;

// Event.current.mousePosition has (0,0) in top-left corner, but the UI system has (0,0) in bottom-left => convert the point
screenPosition.y = sceneview.camera.pixelHeight - screenPosition.y;

// Convert from one camera to the other by using the world point as the intermediate step
var sceneWorldPoint = sceneview.camera.ScreenToWorldPoint(screenPosition);

// Find the required UI objects
var raycaster   = FindObjectOfType<GraphicRaycaster>();
var eventSystem = FindObjectOfType<EventSystem>();

// Convert back to screen point using the UI camera
var gameScreenPoint  = raycaster.eventCamera.WorldToScreenPoint(sceneWorldPoint);
var pointerEventData = new PointerEventData(eventSystem) {position = gameScreenPoint};
var results = new List<RaycastResult>();
raycaster.Raycast(pointerEventData, results);