GUITexture set parent from script broken?

Wierd issue.

I have a large GUITexture used as background, with x,y = 0.3, 0.7, call it background.

I have another prefab, which is an empty GameObject, and within it a bunch of GUITexture and GUIText, call each one a gui entry.

In my script, I instantiate the background, then several of the gui entries. I mean them to appear one below each other, starting from the background. So I instantiate the background, then instantiate each gui entry with the background position + some offset, and it works fine.

But then I want to treat them all as one GameObject, so I try:

guiEntry.transform.parent = background.transform;

Based on Transform.parent documentation: “Changing the parent will modify the parent-relative position, scale and rotation but keep the world space position, rotation and scale the same”. In reality, what happens is that the world position of all the gui entries is reset to be that of the background. Moreover, after this parenting, changing the localPosition of the gui entry does nothing, they still all appear one on top of each other. I tried changing the localPosition from code, and also from the Editor while paused (I can see in the editor that they each have different position, and they all have the same parent, but in reality they appear on top of each other).

Any explanations?

I’ve recreated the following very simple scenario to demonstrate the problem. It always reproduces using unity 4.3, with any GUITexture including the default unity watermark:

using UnityEngine;
using System.Collections;

public class test : MonoBehaviour {
	public Transform guiTexturePrefab;

	// Use this for initialization
	void Start () {
		Transform parent = Instantiate(guiTexturePrefab) as Transform;
		Transform child = Instantiate(guiTexturePrefab, parent.position + new Vector3(0.1f, -0.1f, 0), Quaternion.identity) as Transform;

		// the following line breaks everything
		child.parent = parent;

		// even if I add this after parenting, they still appear on top of each other
		child.position = parent.position + new Vector3(0.1f, -0.1f, 0);
	}
}

This issue does not require a script to recreate. In the editor, just make one GUITexture a child of another, and the child starts ignoring the ‘position’ values in the transform. I ran into this a few weeks ago answering another question. I don’t know if it is a bug in Unity or a limitation.

You can work around the issue by making the parent an empty game object, and then have both GUITexture game objects as children. Give the one that you want to track the parent a position of (0,0,0), and then the child gets whatever relative offset you want…it looks like (0.1, -0.1, 0) for your code.