- Home /
[Unity 4.6 Beta] Rect Transform Position (New UI System)
Hello Unity Users! I have a question. How do I access the Position of a Rect Transform. I don't mean the World space Coords, I mean the Pixel Coordinates. (The Coordinates on Screen Space).
I just cant find its Position (Its not localPosition or position) I have already found the Size which is called sizeDelta but I cant find the position to it.
Thank you very much!
Answer by etaxi341 · Aug 31, 2014 at 09:47 PM
Solution found!
Its called anchoredPosition.
Thanks for that! I was searching for why my modifying the position and localPosition wasn't working, thanks!
Great !! Thanks to your answer I was able to solve my issue.
Just in case someone finds it useful, I wanted to place a Text UI component in the same point where the mouse was located in screen.
To do so, the most important is to consider that the position of Text will be in Screen Coordinates (the same as the $$anonymous$$ouse Pointer ones), and they will be relative to its anchor, so first, we have to set the anchor of this Text on the Bottom Left corner of our screen ($$anonymous$$in, $$anonymous$$ax and Pivot to 0) (considering that we have our Canvas in "Screen Space - Camera" mode).
This way, we could do the following to set the position of our RectTransform to the $$anonymous$$ouse pointer position:
text.rectTransform.anchoredPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
where text is our Text element in our Canvas.
As an FYI to anyone that might stumble upon this: text.rectTransform.anchoredPosition.Set(x, y);
does not work the same as doing ... = new Vector2(x,y);
that had me stumped for a bit.
Answer by Helical · Dec 01, 2014 at 07:41 AM
When you are under a canvas in "Screen Space - Camera" mode, then your position is measured in world coordinates. Its significant since you can't easily compare it to things like Input.mousePosition Vector2.
What you want to do to get the position of the RectTransforms pivot on screen is to use the WorldToScreen() function of the camera that is rendering that UI element. like so.
Vector2 startPointPos = myCam.WorldToScreenPoint(startPoint.position);
anchoredPosition did not work for me; I think Helical is correct that it is necessary to use some form of WorldToScreenPoint(). It took me a while to find a solution because my canvas mode is Screen Space - Overlay so event camera values are null. Sample code below, this is a utility I added to a Script on the UI game object.
/// <summary>
/// Get the screen rect bounds of this button. corners is working storage for 4 points, it is set to the screen space coordinates
/// or use the returned Rect which finds the $$anonymous$$/max
/// </summary>
public Rect GetScreenRect(Vector3[] corners) {
RectTransform rectTransform = (RectTransform)transform;
rectTransform.GetWorldCorners(corners);
float x$$anonymous$$in = float.PositiveInfinity, x$$anonymous$$ax = float.NegativeInfinity, y$$anonymous$$in = float.PositiveInfinity, y$$anonymous$$ax = float.NegativeInfinity;
for (int i = 0; i < 4; ++i) {
// For Canvas mode Screen Space - Overlay there is no Camera; best solution I've found
// is to use RectTransformUtility.WorldToScreenPoint) with a null camera.
Vector3 screenCoord = RectTransformUtility.WorldToScreenPoint(null, corners[i]);
if (screenCoord.x < x$$anonymous$$in) x$$anonymous$$in = screenCoord.x;
if (screenCoord.x > x$$anonymous$$ax) x$$anonymous$$ax = screenCoord.x;
if (screenCoord.y < y$$anonymous$$in) y$$anonymous$$in = screenCoord.y;
if (screenCoord.y > y$$anonymous$$ax) y$$anonymous$$ax = screenCoord.y;
corners[i] = screenCoord;
}
Rect result = new Rect(x$$anonymous$$in, y$$anonymous$$in, x$$anonymous$$ax - x$$anonymous$$in, y$$anonymous$$ax - y$$anonymous$$in);
return result;
}
Hmm, none of these methods is working for me. WorldToScreenPoint is just returning nonsense. And the width and height just end up being the width and height set in the RectTransform--which isn't the size of the object in pixels. Something tells me this is highly dependent on the scale/reference resolution etc.
Note that you should not do these calculations during Awake! From what I found, you can't rely on any RectTransform information during Awake, because it is when it is itself is being initialized.
Also WorldToScreenPoint returns a Vector3 the third parameter is the distance between the object you where pointing and the camera (not so sure about this either) where this is important is when using ScreenToWorldpoint, that you need to provide this distance because if you do ScreenToWorldPoint(5,5,0) then it will return the camera position.
Once again this is all based on experience which I myself dont like this system. I find that using Canvas Scaler properly resolves many of my problems So I aim not to use any of these very volitile techniques.
Answer by tomtomhotep · Jan 03, 2015 at 11:09 AM
Thank you so much, @mwk888. I never would have thought of touching any function dealing with World Space for elements of my Screen Space - Overlay Canvas.
Your function allowed me to complete my script that takes a secondary camera and automatically sets it's Viewport Rect to match a "panel" object in my UI. I placed this script onto the Panel's GameObject. It turns the panel into a "magic window", so-to-speak.
Need to change where the secondary camera view displays during development, just move the panel!
I'm posting the script here, for anyone to use. It's good for rear-view mirrors, mini-maps, etc...
using UnityEngine;
using System.Collections;
public class UICameraWindow : MonoBehaviour {
public GameObject cameraObj; // drag your secondary camera to this in the inspector
private Camera camera;
private RectTransform me;
public bool inUse = false;
private int sW = 0;
private int sH = 0;
// Use this for initialization
void Start()
{
camera = cameraObj.GetComponent<Camera>();
me = this.gameObject.GetComponent<RectTransform>();
if (inUse)
Init();
}
// Update is called once per frame
void Update()
{
if (inUse)
{
if ((Screen.width != sW) || (Screen.height != sH))
Init();
}
}
void Init()
{
sW = Screen.width;
sH = Screen.height;
camera.pixelRect = GetScreenRect(me);
}
public void TurnOn(bool yes)
{
inUse = yes;
if (inUse)
Init();
cameraObj.SetActive(yes);
}
public Rect GetScreenRect(RectTransform rectTransform)
{
Vector3[] corners = new Vector3[4];
rectTransform.GetWorldCorners(corners);
float xMin = float.PositiveInfinity;
float xMax = float.NegativeInfinity;
float yMin = float.PositiveInfinity;
float yMax = float.NegativeInfinity;
for (int i = 0; i < 4; i++)
{
// For Canvas mode Screen Space - Overlay there is no Camera; best solution I've found
// is to use RectTransformUtility.WorldToScreenPoint) with a null camera.
Vector3 screenCoord = RectTransformUtility.WorldToScreenPoint(null, corners[i]);
if (screenCoord.x < xMin)
xMin = screenCoord.x;
if (screenCoord.x > xMax)
xMax = screenCoord.x;
if (screenCoord.y < yMin)
yMin = screenCoord.y;
if (screenCoord.y > yMax)
yMax = screenCoord.y;
}
Rect result = new Rect(xMin, yMin, xMax - xMin, yMax - yMin);
return result;
}
}
Answer by Posch · Jan 10, 2015 at 08:53 PM
You can also easily access the rect of the UI Element if you get the RectTransform Component. Remember to Import UnityEngine.UI !
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class TestClass : MonoBehaviour {
public Rect getScreenCoordinates(RectTransform rT){
return rT.rect;
}
}
Actually, that's the first thing I tried. Didn't work.
In method Init(), I tried
camera.pixelRect = me.rect;
and the camera's viewport went in a completely different place on the screen than where the UI element (this.gameObject in Start()) was. Not only that, the viewport changed positions when I changed the anchor point of the UI element.
BTW, there are no types in your example code that are actually defined in the UnityEngine.UI namespace.
Yep just realized that thought RectTransform was from the UI...
Answer by Razieln64 · Dec 18, 2014 at 10:10 PM
Thanks mwk888! Your script works great. It's really useful.
Your answer
Follow this Question
Related Questions
Change size of the new UI rect transform using scripts 0 Answers
4.6 UI Text rect does not expand automatically 2 Answers
Convert Input.mousePosition to RectTransform pivot position 2 Answers
How to change the Top and Bottom (rect.yMin and yMax) properties of a rectTransform, in a script? 2 Answers
[Unity 4.6 Beta] Anchor snap to button (New UI System) 3 Answers