Search Unity

Unity UI Rect Transform position not updating correctly, but print statements show correct values

Discussion in 'UGUI & TextMesh Pro' started by CheeseOmelette, Jan 11, 2020.

  1. CheeseOmelette

    CheeseOmelette

    Joined:
    Jan 22, 2019
    Posts:
    10
    I have a script that updates the position of 4 UI elements that are children of the same Canvas, as below:



    Sometimes, one of the UI elements goes rogue and its position is not properly updated. Instead, it remains still, as in the following video:



    The first 40 seconds is CORRECT, the remaining is wrong. You can see a white background is separated from the rest. However, it has also happened with just the Text separated or just the BlackOutlinePlayer separated.


    Here is the script component which I attach to each of the objects:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class UIFloat : MonoBehaviour
    6. {
    7.     // Start is called before the first frame update
    8.     public GameObject anchor;
    9.     public Vector3 offset;
    10.    
    11.     void Start()
    12.     {
    13.        
    14.     }
    15.  
    16.     // Update is called once per frame
    17.     void Update()
    18.     {
    19.         if (anchor != null) {
    20.             Vector3 pos = Camera.main.WorldToScreenPoint(anchor.transform.position);
    21.             this.gameObject.GetComponent<RectTransform>().position = pos + offset;
    22.             Debug.Log("The resulting position is literally " + this.gameObject.GetComponent<RectTransform>().position + " for " + this.gameObject.name);
    23.  
    24.  
    25.         }
    26.        
    27.        
    28.         if (this.gameObject.name == "BlackOutlinePlayer" || this.gameObject.name == "WhiteBGPlayer") {
    29.             Debug.Log("Anchored to " + anchor.name + "; coordinates " + this.gameObject.GetComponent<RectTransform>().position.ToString() + "; pos " + anchor.transform.position + "; ");
    30.         }
    31.  
    32.     }
    33. }
    As you can see, I added some logging to try and debug it. However, when I print these values, I see that the Rect Transform for the rogue element is correct, because it is equal to the Rect Transform of the other elements.


    However, the inspector value of whichever element decides to go rogue is different from the others, as shown below.



    All of the values should be equal, but in this case BlackOutlinePlayer has an incorrect value. Of course, I have checked that anchor and offset (from my script) are set properly in the inspector for each of the GUI elements.

    Now that you understand my problem, here's some additional info that might be related:
    • The Camera is moving in the video by an Animator
    • The rogue element is positioned exactly as it would be if the camera was not playing its animation
    • The GUI elements display properly when playing the scene directly. However, when I load the scene through a script, this problem occurs in the opening cutscene. So I wonder if the script isn't fully loading properly or something?
    • Remember, the Inspector values show the rogue element as different, but the script seems to show it working properly
    • My Canvas
    Thank you so much.
     
  2. CheeseOmelette

    CheeseOmelette

    Joined:
    Jan 22, 2019
    Posts:
    10
    Hi, I cannot edit this until the moderator approves it, so let me just add in the proper link for the last image here: https://i.imgur.com/7JJF0mf.png
     
  3. Le_Tai

    Le_Tai

    Joined:
    Jun 20, 2014
    Posts:
    442
    position is world space position. the Pos in inspector is anchored position.
     
    sDatzSD and OWL7seven like this.
  4. CheeseOmelette

    CheeseOmelette

    Joined:
    Jan 22, 2019
    Posts:
    10
    Thanks, this is something to think about. Are you suggesting therefore that the world space position is being updated correctly, but the anchored position is not?

    Do you have any idea why that might be?

    I'm perplexed since the issue only happens when loading the scene from another scene. Also, it is inconsistent and may affect any of the 4 UI elements. I feel like it must have something to do with the camera animation...
     
  5. CheeseOmelette

    CheeseOmelette

    Joined:
    Jan 22, 2019
    Posts:
    10
    Hi, I updated my code to check the anchoredPosition. It is still showing in the script as correct (all the same) but WhiteBGFinicky is appearing in a different location (the same location it would be in if the camera was not moving)

    EDIT: anchoredPosition3D, however, does show different values for the rogue elements.
     

    Attached Files:

    Last edited: Jan 13, 2020
  6. Le_Tai

    Le_Tai

    Joined:
    Jun 20, 2014
    Posts:
    442
    To be honest I didn't read your wall of text, just skimming. I just watched the video and I think you are missing some reference. The fact that there a null check in your code tell me you're not assigning the variable correctly, and instead use the guard clause to swept it under the rug. In the end, however, this is the kind of issue your have to solve yourself. Best advice I can give is to make use of debugging tools, and try to understand why thing happens.
     
  7. CheeseOmelette

    CheeseOmelette

    Joined:
    Jan 22, 2019
    Posts:
    10
    I'm here for help. I'm very much trying to understand. Btw, maybe read the whole post before replying?

    The null check was not hiding an issue; I removed it and there are no errors. Everything is the same as before.

    Would I have posted here without attempting to debug it myself for hours? I'll answer that. Of course I wouldn't.
     
  8. wpetillo

    wpetillo

    Joined:
    May 23, 2017
    Posts:
    24
    It's impossible to tell from the second round of screenshots if you are actually changing the anchored position. In any case,

    Code (CSharp):
    1.             Vector3 pos = Camera.main.WorldToScreenPoint(anchor.transform.position);
    2.             this.gameObject.GetComponent<RectTransform>().position = pos + offset;
    Should be changed to something like this:

    Code (CSharp):
    1. var rect  = anchor.transform as RectTransform;
    2. rect.anchoredPosition += offset;
    Where offset is a Vector2
     
    radiantboy, Bruggi and Majedev like this.
  9. Magasenakwa

    Magasenakwa

    Joined:
    Oct 13, 2018
    Posts:
    91
    Slight derailing of the thread here... I tried spawning a 3d game object inside the scene and setting it's position to match the camera's position then to move forward from there. I kept seeing it spawn off to the right so I tried inspecting the values in the inspector...

    Turns out the world position of both objects are identical... they just don't appear in the same place in the scene. (yes, both are in the root and don't have child objects that might offset the prefab's pivot/spawn/gizmo point)

    So I tried it the other way around, I spawned it, made it a child of the camera and set it's localposition to Vector3.zero. Looking at the object in the scene I see it is a direct child of the camera now, it's transform position shows as 0,0,0 and it is positioned 3.5+ world units t the right of the camera in the scene.

    That was when I completely gave up on Unity. I am now using it solely for this one client of mine for his current project and that is that. Unfortunately, the project is heavily GUI based and Unity can't display the anchor handles around RectTransforms still.

    We've been using unity for over a decade now but never had this much trouble with the most simplest of things. I.e. if 2 items have the same world coordinates, how obvious is it that they should be in the same position in world space?

    Short answer: If you are struggling to get something simple/basic working, just accept it, Unity sucks and there is nothing you can do about it. Move on... :(
     
    ivoras likes this.
  10. OgnjenSelver

    OgnjenSelver

    Joined:
    Aug 27, 2021
    Posts:
    3
    I had same problem. Its fixable but not logical at all... Basically lets say you have 3 buttons on canvas/in canvas element and you move 2 buttons around in script while third you wish to stay static so you dont do changes on it in script. In this case for this static one this error will happend. Basically you have to set position for it each time u move rest of elements