Search Unity

Resolved How do I get Word position of a RectTransform?

Discussion in 'UGUI & TextMesh Pro' started by georgeq, Feb 17, 2023.

  1. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    I have a World Space Canvas that contains some 3D objects. These 3D objects need to be spawned on Awake. Because they need to be offset on the Z axis to be fully visible and because the camera is using perspective projection they look off center, which means, to make them look centered inside the UI element I also need to offset them on the X and Y axes, but to calculate those I need to know the distance from the camera to the UI element. No problem getting the camera's position, but's not so straight forward to get the UI element's world position, I tried: rectTransform.GetWorldCoorinates(corners) and rectTransform.TransformPoint(Vector3.zero) but in both cases I get (0,50,0) no mater where in the world the UI element is located, like if that value was hard coded somewhere inside Unity... by the way I also tried running the code on Start, but that doesn't make any difference.
     
  2. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
  3. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    Thanks but that doesn't work for me, still getting 4 Vectors to the same point (0,50,0).
    Also I tried camera.ScreenToWorldPoint(rectTransform.position) and camera.ScreenToWorldPoint(rectTransform.anchoredPosition3D) and both give the same value (0,14,-16)... actually whatever value I pass to ScreenToWorldPoint() gives me the same result, just as if the return value was hard coded.
     
  4. adamgolden

    adamgolden

    Joined:
    Jun 17, 2019
    Posts:
    1,555
    I just tried a test from scratch. I noticed the RectTransform in question stopped reporting different values when using one of the stretch options in anchor presets (I was logging a first of world corner values in every frame to test). After changing to something else and moving things around, the values being logged started changing again while modifying properties and moving it around.. unfortunately, now I can't get it to break again, and not sure which option or combo of alt+shift+whichever it was that had that issue, but maybe see if the problem still happens when not using any stretch ?

    Edit: ..and it might have just been that I was changing values that weren't affecting the corner I was logging, meaning I probably shouldn't even be trying to help anyone right now, due to probably needing help myself if that's the case lol
     
    Last edited: Feb 17, 2023
  5. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    This is my RectTransform... it's just a container to host the 3D object, so width and height don't matter, they are zero, and scale I think should not play a role in calculating the world position.

    I tried calling Canvas.ForceUpdateCanvases() on Awake and the other calls on Start, but still getting the same results.

    rt.png
     
  6. georgeq

    georgeq

    Joined:
    Mar 5, 2014
    Posts:
    662
    SOLVED:

    You simply cannot trust you'll get any accurate UI related values on Awake nor on Start, whatever query you issue before the canvas has live at least 1 frame will give you a wrong value. So, no matter what info you need from the UI, make sure the canvas has been on screen for at least 1 frame before attempting to retrieve any value... put any UI related calculations in a coroutine and wait at least 1 frame first.
     
  7. frytkihog

    frytkihog

    Joined:
    Aug 21, 2021
    Posts:
    6
    thanks a lot, if you don't want to yield and get it directly in Start though you can call
    LayoutRebuilder.ForceRebuildLayoutImmediate(rectTransform)
    before doing any calculations on UI related stuff and it should work