WorldToScreenPoint is returning weird values

Hello, I’m trying to place a tooltip according to the position of the UI element the mouse is currently over, but I’m getting weird results…instead of values that range from 0 to the screen width/height, I’m getting values in the thousands and negative too.

Any help please? Thanks.

private void PlaceTooltip(UISlot slot)
    {
        Vector2 screenPos = RectTransformUtility.WorldToScreenPoint(Camera.main, slot.transform.position);
        //Debug.Log(string.Format("SlotPos: {0}  ScreenPos: {1}", slot.transform.position, screenPos));

        //screenPos = Camera.main.WorldToScreenPoint(slot.transform.position);
        //Debug.Log(string.Format("SlotPos: {0}  ScreenPos: {1}", slot.transform.position, screenPos));

        int screenHalfWidth = Screen.width / 2;
        int screenHalfHeight = Screen.height / 2;
        //Debug.Log(string.Format("Width/2: {0}  Height/2: {1}", screenHalfWidth, screenHalfHeight));

        Vector3[] slotWorldCorners = new Vector3[4];
        slot.GetComponent<RectTransform>().GetWorldCorners(slotWorldCorners);

        if (screenPos.x < screenHalfWidth && screenPos.y < screenHalfHeight)
        {
            GetComponent<RectTransform>().pivot = new Vector2(0, 0);
            transform.position = new Vector2(slotWorldCorners[2].x, slotWorldCorners[2].y);
        }
        else if (screenPos.x < screenHalfWidth && screenPos.y > screenHalfHeight)
        {
            GetComponent<RectTransform>().pivot = new Vector2(0, 1);
            transform.position = new Vector2(slotWorldCorners[3].x, slotWorldCorners[3].y);
        }
        else if (screenPos.x > screenHalfWidth && screenPos.y > screenHalfHeight)
        {
            GetComponent<RectTransform>().pivot = new Vector2(1, 1);
            transform.position = new Vector2(slotWorldCorners[0].x, slotWorldCorners[0].y);
        }
        else if (screenPos.x > screenHalfWidth && screenPos.y < screenHalfHeight)
        {
            GetComponent<RectTransform>().pivot = new Vector2(1, 0);
            transform.position = new Vector2(slotWorldCorners[1].x, slotWorldCorners[1].y);
        }
    }

WorldToScreenPoint can return negative numbers and numbers that are offscreen if the position sent to it isn’t in the camera’s frustum.

It looks like you’re passing in an object in the Canvas UI, which would almost certainly be well outside the frustum of the camera (as it would be rendering the “real world” and not the UI). I think you don’t need WorldToScreenPoint at all here, and should be able to just use slot.transform.position directly.

2 Likes

Hmm, RectTransformUtility doesn’t have public documentation for the WorldToScreenPoint method, but it does exist. I imagine it’s a wraper for Camera.WorldToScreenPoint Unity - Scripting API: Camera.WorldToScreenPoint. I’d check if slot.transform.position is really on screen and go from there.

That’s the problem, using transform.position works fine, thanks.