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

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

GameObject UI_A= Instantiate(g);
UI_A.transform.position = transform.position;
UI_A.transform.SetParent(transform);
UI_A.transform.localScale = transform.localScale;

UI_A also contain a script that create UI_B which will attach itself to UI_A

//script in UI_A
void Start () {

//float width = GetComponent<RectTransform>().rect.width;
//float height = GetComponent<RectTransform>().rect.height;

Vector3 pos = transform.position;
pos += new Vector3(offsetFromEdge.x, offsetFromEdge.y, 0f);

_UI_B = new UI_B(transform, pos);

}

and in UI_B constructor:

public UI_B(Transform parent, Vector3 pos)
{

GameObject obj = new GameObject();
obj.AddComponent<Canvas>();

var comp = obj.GetComponent<RectTransform>();
comp.pivot = Vector2.zero;
comp.anchorMin = Vector2.zero;
comp.anchorMax = Vector2.zero;

obj.transform.position = pos;

obj.SetParent(parent);
obj.localScale = scale;

}

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.

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

Hi, a couple of things:

  • There is no need to parent an object to itself; this makes no sense. :wink: 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!

1 Like