EventSystem raycasting on World Canvas gameobject always returning worldPosition of zero
I'm trying to get the worldposition of a raycast hit from the EventSystem module. The problem is that the returned worldposition value of the RaycastResult is always Vector3.zero. The distance and gameobject values are correct.
PointerEventData pointerData = new PointerEventData (EventSystem.current);
pointerData.position = Input.mousePosition;
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(pointerData, results);
print (results.Count);
for (int i = 0; i < results.Count; i++) {
print (results [i].worldPosition);
}
Answer by JNylander · May 26, 2017 at 10:35 AM
We'll I dug through the Unity UI Bitbucket repository and found out that GraphicRaycaster.Raycast method doesn't even set a value for RaycastResult.worldPosition, only screenPosition. This is probably why EventSystem.current.RaycastAll doesn't return a worldPosition. The repository points towards Unity version 5.2 but I doubt anything has changed in this regard.
My inelegant solution was to use the screenposition from RaycastResult with Camera.main.ScreenpointToWorldPoint, with RaycastResult.distance as the Z-axis of screenposition. I'll edit this post to tell if this works or not.
[GraphicRaycaster sourcecode from Bitbucket] https://bitbucket.org/Unity-Technologies/ui/src/0155c39e05ca5d7dcc97d9974256ef83bc122586/UnityEngine.UI/UI/Core/GraphicRaycaster.cs?at=5.2
Answer by UnityBrains · Apr 15, 2018 at 07:05 PM
TL;DR Use the physics system to get a world space result for UI raycasting.
I know this is an old thread, but the problem appears to still be present this year.
Thought I'd offer up my solution;
I utilized the PHYSICS raycasting system to get a mouse click world position. I made a game object with only a mesh collider object (a quad in my case, but any physics collider object would work), put the mesh collider on the UI layer and did a regular physics raycast against that.
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit rHit;
Physics.Raycast(ray, out rHit, Mathf.Infinity, LayerMask.GetMask("UI"));
gameObject.transform.position = rHit.point;
From here, you can obviously do checks to ensure you're using the correct raycast hit results. I was able to skip that because this quad was the ONLY object in the UI layer that could return a physics raycast result.
Your answer
Follow this Question
Related Questions
If I disable/enable my canvas (pause game menu), controller navigation in the canvas stops to work? 1 Answer
OnPointerEnter blocked by something 2 Answers
EventSystem.current is returning null 0 Answers
UI buttons don't work with Canvas Render Mode: Screen Space - Camera. 2 Answers
How to render an image always on top? Already tried some solutions 0 Answers