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.
Did some more tests, it seems that
- The Raycast methods only work in play mode
- 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…
- It only works in 2D mode & orthographic directly from the front.
- It requires that the canvas is set to Screen Space - Camera, and that a render camera is set.
- 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);