Project files: https://github.com/Sebastian-Nielsen/makingSenseOfPositions

Note: There are no scripts running, all I am doing in between each picture is manually changing the x-coordinate in the inspector of the given gameObject.

See the problem: Gif

Here we got my lovely little scene enter image description here

Now, take note on the x-position of the tile the dark soldier is standing upon; it's -13.78. enter image description here Take a look at the Dark Soldier's x-position now. There is a difference of 3 between those two on the x-axis! enter image description here

Now, look what happens when I change the x-coordinate of the Dark Soldier to -13 to match that of the tile. (I expect the Dark Soldier to now be precisely on top of the tile he was standing on in the first picture -- maybe he was a little off in that pic). enter image description here enter image description here

Wait what? He moved away from the tile at position x=-13.

Why is that?! I think I'm going crazy! Please make sense of this, why is this happening?

  • \$\begingroup\$ Please provide more info on how we could simulate this problem and see what's wrong, maybe a script snipper. Lots of things could happen there and we have not enough info to investigate \$\endgroup\$ – Panagiotis Iatrou Apr 6 at 10:15
  • 1
    \$\begingroup\$ What happened between the screenshots for example \$\endgroup\$ – Panagiotis Iatrou Apr 6 at 10:16
  • \$\begingroup\$ All I did was manually type into the inspector of the given gameObject a new x-coordinate. There doesn't happen anything in between, i.e. there are no scripts running. \$\endgroup\$ – Sebastian Nielsen Apr 6 at 10:18
  • \$\begingroup\$ There is an Animator component attached to the second dark Soldier so I think this might be caused by an animation if you have assigned one to an animator. So I think for the testing purposes just remove or disable animator from the object and see if it does the trick. \$\endgroup\$ – Swati Apr 6 at 10:38
  • \$\begingroup\$ Then probably, the Tiles GameObject (I suppose it is the parent of all the tiles), has an offset. Set it's position to Zero. \$\endgroup\$ – Panagiotis Iatrou Apr 6 at 10:39

You've done a few things here that are making this appear more confusing than it needs to.

First: your tiles are all children of a parent object - which can be good for scene organization - but it means you're not comparing apples to apples when you look at the transform values (which show you the localPosition, localEulerAngles, and localScale properties):

  • Your Dark Knight has no parent, so its position/rotation/scale values are relative to your world coordinate system.

  • Your tiles are children of the Tiles game object, so their position/rotation/scale values are relative to their parent.

Again, this isn't bad, but it introduces an extra step: you have to consider the parent's transform too. And you've shifted the Tiles parent object by (-2, 1, -45)

That means the tile that's at (-13.78, 3.87, 44.517) relative to this parent is actually at

(-13.78, 3.87, 44.517) + (-2, 1, -45) = (-15.78, 4.87, -0.483) 

in the world.

If you want to do easy apples-to-apples comparisons in worldspace between objects in different containers, it can help to keep the container at (0, 0, 0) and default scale & rotation.

This won't be a problem in scripts, of course, since you can just ask an object for its transform.position (not the .localPosition you see in the Inspector), which automatically factors in the whole parent/grandparent chain and reports back the value in world space.

You can get a similar effect in editor by kicking the object of interest out of the parent - Unity will automatically adjust its local transform values to try to keep it at the same location/orientation/scale, baking its world transform down into its local transform for you to read. Then you can reverse the operation to put it back in its original place in the hierarchy.

The next funny thing we can reveal by putting the scene transform gizmo toggles at the top toolbar into "Pivot" mode:

Pivot display on tile

We can see the transform gizmo arrows cross at the pivot of the object, right in the center of the tile, where we'd intuitively expect to find it.

But when we position the Dark Knight at the location we calculated above to adjust for the parent offset, we see this:

Pivot display on knight

As we wanted, the pivot is positioned perfectly on top of the tile. But the visible sprites are shifted significantly from this pivot point!

It looks like you've set up this asset so all the body parts are down and to the right of the parent's origin/pivot point.

Dark Knight in prefab editor

Usually we want to set up our characters so the root transform's origin is either at their center of mass, or at the base of their feet (for ease of positioning characters of different heights on the same ground level).

If there are no animations on the object, we can usually fix this with a trick similar to the one above: kick all the child objects out of the parent, move the parent to the location where we want it relative to the children, then add the children back into the parent, so they take on new local positions inside it.

But with animations this is tricky: the first frame the animation plays, it will usually shove everything back to its recorded position in the animation, which was the old offset we wanted to remove! So you may need to remake your animation on this asset to get the pivot where you want it.

A cheap trick you can use to avoid this work is to create a new parent object at the place where you want the pivot, then parent your whole prefab to the new parent, and then overwrite your prefab with the new parent. You deal with one extra layer of transformation this way, but it lets you quickly correct for an unwanted transformation on the child objects.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.