Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Use GraphicRaycaster in Editor Mode

Discussion in 'UGUI & TextMesh Pro' started by Martin_Gonzalez, Jun 22, 2019.

  1. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    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.

    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEditor;
    3. using UnityEngine;
    4. using UnityEngine.EventSystems;
    5. using UnityEngine.UI;
    6.  
    7. [InitializeOnLoad]
    8. public class RightClick : Editor{
    9.     static GraphicRaycaster raycaster;
    10.     static PointerEventData pointerEventData;
    11.     static EventSystem eventSystem;
    12.  
    13.     static RightClick(){
    14.         SceneView.onSceneGUIDelegate += OnSceneGUI;
    15.     }
    16.  
    17.     static void OnSceneGUI(SceneView sceneview){
    18.         if (Event.current.button == 1) {
    19.             if (Event.current.type == EventType.MouseDown) {
    20.                 raycaster = FindObjectOfType<GraphicRaycaster>();
    21.                 eventSystem = FindObjectOfType<EventSystem>();
    22.                 pointerEventData = new PointerEventData(eventSystem) { position = Event.current.mousePosition};
    23.  
    24.                 List<RaycastResult> results = new List<RaycastResult>();
    25.                 raycaster.Raycast(pointerEventData, results);
    26.  
    27.                 foreach (RaycastResult result in results) {
    28.                     Debug.Log("Hit: " + result.gameObject.name);
    29.                 }
    30.             }
    31.         }
    32.     }
    33. }
     
  2. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
  3. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    795
    Hi Martin! Did you ever figure this out? Trying to achieve the same thing. :)
     
  4. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    Nope :(
     
  5. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    795
    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
     
  6. Martin_Gonzalez

    Martin_Gonzalez

    Joined:
    Mar 25, 2012
    Posts:
    361
    There must be a way, I want to throw a raycast and get all UIs I've hit
     
  7. TheoKiloo

    TheoKiloo

    Joined:
    Dec 5, 2016
    Posts:
    10
    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)

    upload_2019-8-29_0-45-29.png


    Code (CSharp):
    1. Vector3 screenPosition = Event.current.mousePosition;
    2.  
    3. // Event.current.mousePosition has (0,0) in top-left corner, but the UI system has (0,0) in bottom-left => convert the point
    4. screenPosition.y = sceneview.camera.pixelHeight - screenPosition.y;
    5.  
    6. // Convert from one camera to the other by using the world point as the intermediate step
    7. var sceneWorldPoint = sceneview.camera.ScreenToWorldPoint(screenPosition);
    8.  
    9. // Find the required UI objects
    10. var raycaster   = FindObjectOfType<GraphicRaycaster>();
    11. var eventSystem = FindObjectOfType<EventSystem>();
    12.  
    13. // Convert back to screen point using the UI camera
    14. var gameScreenPoint  = raycaster.eventCamera.WorldToScreenPoint(sceneWorldPoint);
    15. var pointerEventData = new PointerEventData(eventSystem) {position = gameScreenPoint};
    16. var results = new List<RaycastResult>();
    17. raycaster.Raycast(pointerEventData, results);