- Home /
Converting UI RectTransform to Screen Pixel and vice-versa
I am creating an Image
that showed when user touch the screen and automatically changing it position based on current touch position. my Canvas
Render mode are Screen Space Overlay.
also I am creating an Image
with fixed position, and when user touch the screen, a script will determine is touch are touching this Image
and resulting the touch coordinate relative to Image position in screen Pixel
so my question is how to convert screen pixel Coordinate to UI RectTransform
and convert it back to screen Pixel Coordinate?
notes : I have searching about RectTransformUtility but i don't know what the function used for and how I use it.
Answer by Mmmpies · Dec 24, 2014 at 09:37 PM
You're in luck, I'm procrastinating from stuff I should be doing and this is just the sort of thing that can make it seem like I'm doing something important!
which is why I've spent half an hour trying to get this working. Can't say I can guarantee what the results are but I got it outputting a result.
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class RectUtil : MonoBehaviour {
public Camera MainCam;
public RectTransform myRectT;
private Vector3 result;
//225,96,40
//ScreenPointToWorldPointInRectangle(rect: RectTransform, screenPoint: Vector2, cam: Camera, worldPoint: Vector3): bool;
// Use this for initialization
void Start () {
Vector2 myV2 = new Vector2(0,24);
Debug.Log (RectTransformUtility.ScreenPointToWorldPointInRectangle(myRectT,
myV2,
MainCam,
out result));
Debug.Log (result);
}
}
thanks!!, now i know that the output is not bool, but is in the last parameter. i will make experiment with it later.......
Took me a while and some random typing to get it to work. The documentation is poor but the UI is new so maybe not so surprising.
Seen a couple of people who want this kind of functionality so feel free to make it public if you get it working more than printing out results.
Thanks for marking a correct answer :¬)
+ 1
for "I'm procrastinating from stuff I should be doing and this is just the sort of thing that can make it seem like I'm doing something important"
Answer by mrpmorris · Dec 10, 2016 at 03:18 PM
Although the help says that it returns coordinates in world space, they are actually in screen space. So the solution is simple:
public Rect GetScreenCoordinates(RectTransform uiElement)
{
var worldCorners = new Vector3[4];
uiElement.GetWorldCorners(worldCorners);
var result = new Rect(
worldCorners[0].x,
worldCorners[0].y,
worldCorners[2].x - worldCorners[0].x,
worldCorners[2].y - worldCorners[0].y);
return result;
}
@mrpmorris your snippet seems to not adjust for canvas scaled size for different screen sizes?
@mrpmorris I would assume that the coordinates are in world space for world space canvases, while for screen space / screen space overlay this code should work
Answer by sisse008 · Sep 02, 2019 at 01:57 PM
expending on mrpmorris solution:
public Rect GetScreenCoordinatesOfCorners(RectTransform uiElement)
{
var worldCorners = new Vector3[4];
uiElement.GetWorldCorners(worldCorners);
var result = new Rect(
worldCorners[0].x,
worldCorners[0].y,
worldCorners[2].x - worldCorners[0].x,
worldCorners[2].y - worldCorners[0].y);
return result;
}
public Vector2 GetPixelPositionOfRect(RectTransform uiElement)
{
Rect screenRect = GetScreenCoordinatesOfCorners(uiElement);
return new Vector2(screenRect.center.x, screenRect.center.y);
}
By the way turns out, for my purpose, that I had to flip the y axis.
return new Vector2(screenRect.center.x, Screen.height - screenRect.center.y);
Answer by bab202 · Dec 14, 2019 at 04:08 PM
The general logic to convert world position (Vector3) to screen position or anchored position (Vector2) is:
Get the worldPoint by
gameObject.transform.position
From worldPoint, get the screenPoint by
RectTransformUtility.WorldToScreenPoint
From screenPoint, translate it to localPointInRectangle (anchoredPoint) by
RectTransformUtility.ScreenPointToLocalPointInRectangle
The code function:
public static Vector2 WorldPointToLocalPointInRectangle(Vector3 worldPoint,
Camera camera, Canvas canvas, RectTransform parentRect) {
var screenPoint = camera.WorldToScreenPoint(worldPoint);
// Translate screen point to local point of a parent rect transform
// If canvas render mode is ScreenSpace-Overlay, camera param should be null
// Ref: https://docs.unity3d.com/ScriptReference/RectTransformUtility.ScreenPointToLocalPointInRectangle.html
RectTransformUtility.ScreenPointToLocalPointInRectangle(
parentRect, screenPoint,
canvas.renderMode == RenderMode.ScreenSpaceCamera ? canvas.worldCamera : null,
out var result);
return result;
}
Answer by maroon3d · Jan 08, 2020 at 11:54 AM
I spent several hours and finally found this workaround:
Even when gameObject has a RectTransform, it also has a transform component that is invisible in the inspector, but still accessible through a script:
// RECT TRANSFORM TO SCREEN SPACE
public Vector2 LocalPositionToScreenPosition(RectTransform _rectTransform)
{
Vector2 screenCenter = new Vector2(Screen.currentResolution.width / 2,
Screen.currentResolution.height / 2);
Vector2 output = (Vector2)cam.WorldToScreenPoint(_rectTransform.position) - screenCenter;
Debug.Log(output);
return output;
}