Search Unity

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:
    812
    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:
    812
    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);