DeveloperApps
DeveloperApps

Reputation: 803

Local position and global position

I have a target that is the parent of a cube For target Position(5000, 0, 0)

GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.localPosition = new Vector3(0, 0, 0);
cube.transform.localScale = new Vector3(100, 100, 100);
cube.name = "XXXXX";

cube.transform.parent = target.transform;

The code below should add a cube inside the target, i.e. globally in (5000, 0, 0)

But the object is added in the global center itself (0,0,0)

What am I doing wrong?

enter image description here

Upvotes: 1

Views: 4660

Answers (2)

Ruzihm
Ruzihm

Reputation: 20249

Use Transform.SetParent with the worldPositionStays parameter set to false:

GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.localPosition = new Vector3(0, 0, 0);
cube.transform.localScale = new Vector3(100, 100, 100);
cube.name = "XXXXX";

cube.transform.SetParent(target.transform, false);

From the documentation:

This method is the same as the parent property except that it also lets the Transform keep its local orientation rather than its global orientation. This means for example, if the GameObject was previously next to its parent, setting worldPositionStays to false will move the GameObject to be positioned next to its new parent in the same way.

The default value of worldPositionStays argument is true.

Upvotes: 1

Milan Egon Votrubec
Milan Egon Votrubec

Reputation: 4049

What you're doing here is instantiating a cube, at (0,0,0). After that, you're then parenting the cube to your current object. The cube, is STILL sitting at (0,0,0). So, locally, your cube is going to have a local offset to make sure the cube is still at the origin where it was created.

BUT, you do have the option when instantiating an object in either local or world space. To quote from the Unity docs here:

"By default the parent of the new object is null; it is not a "sibling" of the original. However, you can still set the parent using the overloaded methods. If a parent is specified and no position and rotation are specified, the original object's position and rotation are used for the cloned object's local position and rotation, or its world position and rotation if the instantiateInWorldSpace parameter is true. If the position and rotation are specified, they are used as the object's position and rotation in world space."

Note that CreatePrimitive DOESN'T have the option of using either local or world space. It's up to you to position the primitive yourself.

So, in your case, you could want to do this:

GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.parent = target.transform;
cube.transform.localPosition = new Vector3(0, 0, 0);
cube.transform.localScale = new Vector3(100, 100, 100);
cube.name = "XXXXX";

Note above that you parent the child first, THEN set the local position. Your first block of code set the local position of the parent, which is the world because it's not a child of anything. But if you parent the object first, then you're setting the local position to that of the parent, and now you'll see the behaviour you expect.

Upvotes: 2

Related Questions