Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Child UI world position shifted after parenting to a gameobject UI element

Discussion in 'UGUI & TextMesh Pro' started by warance, Aug 13, 2015.

  1. warance

    warance

    Joined:
    May 4, 2014
    Posts:
    11
    For my UIs there is this chain of hierarchy created as follow

    • MainCanvas(screenspace-camera, with plane distance 0.31(near plane is 0.3))
      • EmptyPanel
        • UI_A(with rect transform)
          • UI_B(with rect transform)
    Emptypanel contains a script that creates UI_A at runtime and parent UI_A to itself

    Code (CSharp):
    1. GameObject UI_A= Instantiate(g);
    2. UI_A.transform.position = transform.position;
    3. UI_A.transform.SetParent(transform);
    4. UI_A.transform.localScale = transform.localScale;
    UI_A also contain a script that create UI_B which will attach itself to UI_A

    Code (CSharp):
    1. //script in UI_A
    2. void Start () {
    3.  
    4. //float width = GetComponent<RectTransform>().rect.width;
    5. //float height = GetComponent<RectTransform>().rect.height;
    6.  
    7. Vector3 pos = transform.position;
    8. pos += new Vector3(offsetFromEdge.x, offsetFromEdge.y, 0f);
    9.  
    10. _UI_B = new UI_B(transform, pos);
    11.  
    12. }
    and in UI_B constructor:

    Code (CSharp):
    1. public UI_B(Transform parent, Vector3 pos)
    2. {
    3.  
    4. GameObject obj = new GameObject();
    5. obj.AddComponent<Canvas>();
    6.  
    7. var comp = obj.GetComponent<RectTransform>();
    8. comp.pivot = Vector2.zero;
    9. comp.anchorMin = Vector2.zero;
    10. comp.anchorMax = Vector2.zero;
    11.  
    12. obj.transform.position = pos;
    13.  
    14. obj.SetParent(parent);
    15. obj.localScale = scale;
    16.  
    17. }
    So, when offsetFromEdge is (0,0), UI_B appear nice at where it should be, right on top of UI_A with localPosition being (0,0,0). However when i set the value of offsetFromEdge to (1,1), UI_B localposition become insanely huge (3611.xx, 3611.xx, 0);

    These values are displayed on the RectTransform component's Pos X and Pos Y which i believe is the same a UI_B's transform.localPosition.

    I have no idea what causes this behavior.
     
  2. warance

    warance

    Joined:
    May 4, 2014
    Posts:
    11
    Ok, someone suggest that i should the UI element to their parent then modify their local position to where i want them to be, while someone else pointed out that I should be using anchoredPosition instead or transform.position/localposition.

    I manage to achieve what I wanted to do by setting the localPosition(well since I am directly modifying the localposition, the object are appearing where they are suppose to be) but it bugs me now that I am not doing things the right way.

    So how do one really create a UI element from prefab and position them in the scene? RectTransform.localPosition or RectTransform.anchoredPosition
     
  3. Senshi

    Senshi

    Joined:
    Oct 3, 2010
    Posts:
    557
    Hi, a couple of things:

    - There is no need to parent an object to itself; this makes no sense. ;) UI_A's parent would be EmptyPanel, and EmptyPanel's would be the Canvas.
    - To keep the local orientation when parenting, use the overloaded version of SetParent() with "worldPositionStays" set to false.
    - You are using a class's constructor to create a GameObject (new UI_B()). Unity typically does things a tad differently; I would suggest looking into using Prefabs (and the related Instantiate() functionality).

    Cheers!
     
    kpgbrink likes this.