Search Unity

  1. Dismiss Notice
  2. All Pro and Enterprise subscribers: find helpful & inspiring creative, tech, and business know-how in the new Unity Success Hub. Sign in to stay up to date.
    Dismiss Notice

Bug Positioning Visual Elements in World Space

Discussion in 'UI Toolkit' started by MousePods, Apr 6, 2021.

  1. MousePods

    MousePods

    Joined:
    Jul 19, 2012
    Posts:
    284
    Hi!

    I feel like this isn't a bug and that I am doing something wrong, but I want to see if this might be a bug.

    All I am trying to do is get a GameObjects world position, translate it to screen space, and position a visual elements over it.

    First I just used:

    Code (CSharp):
    1. Vector3 p = Camera.main.WorldToScreenPoint(position * scaleFactor);
    Screen Shot 2021-04-05 at 10.06.32 PM.png

    It was always offset. I then used the code below:

    Code (CSharp):
    1.     public static Vector3 GetGameObjectScreenPosition(Vector3 position, float scaleFactor)
    2.     {
    3.         Vector3 p = Camera.main.WorldToScreenPoint(position * scaleFactor);
    4.  
    5.         p.z = 0;
    6.         p.y -= Screen.height;
    7.         p.y = Mathf.Abs(p.y);
    8.  
    9.         return p;
    10.     }
    Screen Shot 2021-04-05 at 10.27.20 PM.png

    It helped position it much closer, but, as you can see, the top right corner of the VisualElement rectangle is not centered on the white dot.

    Plus this only worked on the native resolution (scale with screen panel settings). On any other resolution it is completely off on both the x and the y.

    I feel like I am possible missing something or is this a bug being worked on?

    EDIT: The other direction works perfectly. ScreenToWorld for positioning world objects over VisualElements.

    Code (CSharp):
    1.     public static Vector3 GetVisualElementWorldPosition(VisualElement ve, float scaleFactor)
    2.     {
    3.         Vector3 position = Camera.main.ScreenToWorldPoint(ve.worldBound.center * scaleFactor);
    4.         position.z = 0;
    5.                
    6.         // Because camera 0,0 is bottom-left and UIToolkit is top-left
    7.         position.y *= -1;
    8.  
    9.         return position;
    10.     }
    Thanks!
     
  2. MousePods

    MousePods

    Joined:
    Jul 19, 2012
    Posts:
    284
    The solution to the first problem is that you have to wait until the end of the frame for it to work. Any Unity Developers know if this is a bug and should be reported?

    However, this only works on the native resolution. How do you make the code work on all resolutions? Using the scale factor doesn't seem to help in this instance.
     
  3. Kazko

    Kazko

    Joined:
    Apr 2, 2014
    Posts:
    55
    I saw a weird issue couple of days ago, which I did not have time to investigate. I moved to another computer where suddenly my UI panels were completely off. I was desperate after hours of trying to figure out why and then discovered that when I set Windows resolution scale to 100%, the panels were OK. The former computer had 100%, the new station had a larger monitor and 125% scale set in windows, which was throwing the UI system off.

    Then I made new panel settings asset and I think it fixed the issue. Again, I did not investigate if this translates to build, or it was just in editor, etc. Anyway I added this to my list of things to look at when debugging weird Unity behavior.
     
    MousePods likes this.
  4. MousePods

    MousePods

    Joined:
    Jul 19, 2012
    Posts:
    284
    Hey!

    Thanks for the reply. This unfortunately isn't the issue. It works on the native resolution, but with the scale factor, it doesn't work on other resolutions because the UI is scaled down. However, in this instance, the scale factor doesn't seem to be of help.

    EDIT: I was able to figure out the second issue with the scale factor. It seems you need to divide instead of multiplying.

    Code (CSharp):
    1.     public static Vector3 GetGameObjectScreenPosition(Vector3 position, float scaleFactor)
    2.     {
    3.         Vector3 p = Camera.main.WorldToScreenPoint(position);
    4.         p.z = 0;
    5.         p.x /= scaleFactor;
    6.         p.y = Screen.height - p.y;
    7.         p.y /= scaleFactor;
    8.  
    9.         return p;
    10.     }
    I still don't know if the first issue is a bug or not.
     
    Last edited: Apr 7, 2021
unityunity