Reputation: 23234
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
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
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
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
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