- Home /
Why can't I set transform.position on a child object?
In code, I can set the transform.position on a game object and see the result in game.
In the editor, I can set the position of an object, and then set the object as a child of another. When I do this, the position values displayed are changed to localPosition equivalents that keep the object in the same place in space, which makes sense. This made me presume that something analogous would happen when working in code.
However, if there is a transform.parent of an object, setting the transform.position yields no result in game. The debugger seems to confirm that the transform.position assignment is undone after parenting, or the assignment is ignored if it's already parented.
I can get around this by using math relative to the local space and setting the transform.localPosition on the child object. I was just wondering if anyone knew what was going on here. Is transform.position effectively read only for getting child object global position? Does Unity actually have global position assignment silently fail for child objects? Am I misunderstanding things?
Some examples:
Setting relative position works for child:
bar.transform.parent = transform;
bar.transform.localPosition = new Vector3(0f, 0f, 1f);
Debug.Log("local position: " + bar.transform.localPosition); // 0, 0, 1
Setting global position works for unparented object:
bar.transform.position = new Vector3(0f, 0f, 1f);
Debug.Log("global position: " + bar.transform.position); // 0, 0, 1
Setting global position for child doesn't work:
bar.transform.parent = transform;
bar.transform.position = new Vector3(0f, 0f, 1f);
Debug.Log("global position: " + bar.transform.position); // 0,0,0
Setting global position for unparented object works, but is undone when parented:
bar.transform.position = new Vector3(0f, 0f, 1f);
Debug.Log("global position: " + bar.transform.position); // 0,0,1 applied
bar.transform.parent = transform;
Debug.Log("global position after parenting: " + bar.transform.position); // 0,0,0 again
I can't reproduce your 3. and 4. example. Parenting an object does change the localPosition / localRotation so that the position and rotation stays the same.
When setting position / rotation of a child it will be moved / rotated in worldspace and unity transforms the position into localPosition / localRotation
Can you post a fully working example? For example where do you execute this snippets? Awake / Start / Update? Do you even execute it at runtime or inside the editor? Are your objects real scene objects or maybe prefabs?
Thanks for looking. I ran it inside the editor and the script is on a real scene object in the hierarchy, just an empty object at 0,0,0 with nothing but this script. I was seeing the issue in Update() because I wanted to change the position at runtime, but for this test, it occurs in Start() too. Here's a full example of case 3.
void Start()
{
var bar = new GameObject();
bar.transform.parent = transform;
bar.transform.position = new Vector3(0f, 0f, 1f);
Debug.Log("bar's global position: " + bar.transform.position); // 0, 0, 0
}
Answer by Bunny83 · Sep 18, 2013 at 06:38 PM
I've created an empty gameobject at 10,0,0 and attached a new c# script with your code. When i execute the scene i get:
bar's global position: (0.0, 0.0, 1.0)
When i select the child object in the inspector it shows the correct local position of
(-10.0, 0.0, 1.0)
which equals the world position (0.0, 0.0, 1.0)
Have you actually tested your example?
If i move the parent to 0,0,0 i also get the same output.
The only way i can get your output is when the parent objects scale is set to 0,0,0. In this case all child objects have to be at the parents origin since it's not possible to calculate a localPosition inside a zero-space.
The only way i can get your output is when the parent objects scale is set to 0,0,0. In this case all child objects have to be at the parents origin since it's not possible to calculate a localPosition inside a zero-space.
This was the issue and the explanation I needed to make sense of it! I was adding various GUI type components to the object and needed 0,0,0 scale for that.
For the example simplified test case, I had stripped everything else out and still got this side-effect. I didn't notice I had still left the 0 scale on the parent.
Big thanks!
Biiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiig Thanks. I would never thought that the scale of the parent would cause me so much trouble.. Thanks again!
Answer by wiiarethesound · Sep 17, 2013 at 10:53 PM
transform.position refers to the Transform's global position.
transform.localPosition refers to the Transform's position relative to it's parent.
Yup, but the issue I'm having is being able to set transform.position in code. See the details above.
I edited the short version of the question in the title to better reflect the issue and added examples.
Your answer
Follow this Question
Related Questions
Make a simple tree 1 Answer
Is there a way to lock the local position of a game object? 0 Answers
object's children not moving with it when using a Lerp-ing coroutine 0 Answers
Child Object Left Behind when Parent Moves at Start of Scene 1 Answer
Set Position and Rotation with another GameObject as Pivot (Script) 0 Answers