Peter Morris
Peter Morris

Reputation: 23234

How do I find which object is EventSystem.current.IsPointerOverGameObject detecting?

I am using EventSystem.current.IsPointerOverGameObject in a script and Unity returns True even though I would swear there is no UI/EventSystem object beneath the pointer.

How can I find information about the object the EventSystem is detecting?

Upvotes: 9

Views: 22750

Answers (4)

Mark Day
Mark Day

Reputation: 17

From the discussion above i used it this way

        /// <summary>
    /// Is the pointer hovering over a game object with the given name
    /// </summary>
    /// <param name="name">Name of the game object hovering over</param>
    /// <returns>Status</returns>
    private bool IsPointerOverGameObjectName(string name)
    {
        PointerEventData pointer = new PointerEventData(EventSystem.current);
        pointer.position = Input.mousePosition;

        List<RaycastResult> raycastResults = new List<RaycastResult>();
        EventSystem.current.RaycastAll(pointer, raycastResults);

        if (raycastResults.Count > 0)
        {
            foreach (var go in raycastResults)
            {
                if (go.gameObject.name == name)
                {
                    return true;
                }
            }
        }

        return false;
    }

Upvotes: 0

Ilya Dvorovoy
Ilya Dvorovoy

Reputation: 414

I've stumbled upon this thread and wasn't quite happy with the solution provided, so here's another implementation to share:

public class StandaloneInputModuleV2 : StandaloneInputModule
{
    public GameObject GameObjectUnderPointer(int pointerId)
    {
        var lastPointer = GetLastPointerEventData(pointerId);
        if (lastPointer != null)
            return lastPointer.pointerCurrentRaycast.gameObject;
        return null;
    }

    public GameObject GameObjectUnderPointer()
    {
        return GameObjectUnderPointer(PointerInputModule.kMouseLeftId);
    }
}

Looking at the EventSystem's editor output showing names for the GameObjects, I decided that some functionality was already there and there should be means of using it. After diving into the opened source of the forementioned EventSystem and IsPointerOverGameObject (overrided in PointerInputModule), I thought it'll be easier to extend the default StandaloneInputModule.

Usage is simple, just replace the default one added on the scene with the EventSystem and reference in code like:

private static StandaloneInputModuleV2 currentInput;
private StandaloneInputModuleV2 CurrentInput
{
    get
    {
        if (currentInput == null)
        {
            currentInput = EventSystem.current.currentInputModule as StandaloneInputModuleV2;
            if (currentInput == null)
            {
                Debug.LogError("Missing StandaloneInputModuleV2.");
                // some error handling
            }
        }

        return currentInput;
    }
}

...

var currentGO = CurrentInput.GameObjectUnderPointer();

Upvotes: 6

Programmer
Programmer

Reputation: 125435

You can find out more info about which GameObject EventSystem is detecting by implementing IPointerClickHandler and overriding the OnPointerEnter function.

If this is a UI component such as Image/RawImage and others, you want to detect, this should do it:

using UnityEngine.EventSystems;
public class MouseEnterScript: MonoBehaviour, IPointerEnterHandler
{
    public void OnPointerEnter(PointerEventData eventData)
    {
        Debug.Log("Name: " + eventData.pointerCurrentRaycast.gameObject.name);
    }
}

If this is a Mesh with a Collider(3D) such as Box Collider, Add PhysicsRaycaster to the Camera then use the first code in this answer to detect which GameObject the mouse is over.

void Start()
{
    Camera.main.gameObject.AddComponent<PhysicsRaycaster>();
}

If this is a SpriteRenderer with a 2D Collider such as Box Collider 2D, Add Physics2DRaycaster to the Camera then use the first code in this answer to detect which GameObject the mouse is over

void Start()
{
    Camera.main.gameObject.AddComponent<Physics2DRaycaster>();
}

Upvotes: 1

Umair M
Umair M

Reputation: 10750

In your update() :

 if(Input.GetMouseButton(0))
 {
     PointerEventData pointer = new PointerEventData(EventSystem.current);
     pointer.position = Input.mousePosition;

     List<RaycastResult> raycastResults = new List<RaycastResult>();
     EventSystem.current.RaycastAll(pointer, raycastResults);

     if(raycastResults.Count > 0)
     {
         foreach(var go in raycastResults)
         {  
             Debug.Log(go.gameObject.name,go.gameObject);
         }
     }
 }

Upvotes: 16

Related Questions