# How to move object on local space not object space in unity

I am watching this (game dev, space parenting & rotation) Sebastian Lague video and found that there are three spaces actually (not two) and these are world space, local space and object space.

1. World space: The static space (0,0,0)
2. Object space: related to the object space
3. Local Space: related to the parent of the object

I am amazed that i didn't find the distinction between these two spaces(local and object) on official unity forms but actually it exists. My question is that why there is no Space.Local? I found that there are Space. Self and Space.World. Space.Self is refer to object space. I can move my object to object space using this

    void Update () {
transform.Translate(new Vector3(0,0,1) * Time.deltaTime * 2,Space.Self);
}


And i can move my object to world space using this

void Update () {
transform.Translate(new Vector3(0,0,1) * Time.deltaTime * 2,Space.World);
}


but there is no support for local space that i could move the object to local space (means move the object related to its parent object). There is a fair distinction between Local and Object space but unity didn't consider it i guess or i am wrong.

I think that there is a bit of misunderstanding with these 3 spaces.

Basically you should focus on two spaces: World and Local. Object space has meaning when you take about vertices positions. Example, if an object has a local position of (1, 0, 0), if means its center is one unit away from the parent center on the x axis. but so what would an object space position of (1, 0, 0) mean? That the objects center is one unit away from itself? Only the object's vertices are given in object space (meaning, where is this vertex compared to the center of the object). Vertex shaders use this for example. But in your everyday use of Unity you don't use it.

So why is there a Space.Self?

Well, according to the doc, what it does is:

Applies transformation relative to the local coordinate system.

So Space.World is world coordinate, and Space.Self is local coordinate.

In your example, you move the object in local space. Moving it in object space doesn't mean anything.

Finally note that you can also move in local space by editing transform.localPosition instead of transform.position, But this would be the same as a translation using Space.Self or Space.World respectively.

Hope this clears things up a bit

transform.Translate does something a little funny. The Space you select picks the directions that it moves the object, but doesn't scale the translation. The actual translation vector is always applied in worldspace, and you're just selecting whether to rotate the direction to match the object's local axes, or not.

Since an object might not have a parent at all to fetch a direction from, I'm guessing they skipped the extra conditional logic for this case because it doesn't come up in practice much that you want to move an object with respect to its parent while ignoring its parent's scale. More often, if we're doing parent-space positioning, we want to use something like:

transform.localPosition += translation;


which allows the parent's scale to affect the resulting position.

But, if you really want transform.Translate style behaviour and syntax for this case, we can add it as an extension method:

public enum Spaces {
World,
Parent,
Self
}

public static class SpaceExtension {

public static void Translate(this Transform transform, Vector3 translation, Spaces ralativeTo) {
switch(relativeTo) {
case Spaces.World:
transform.position += translation;
break;
case Spaces.Self:
transform.position += transform.rotation * translation;
break;
case Spaces.Parent:
// Fall back on world space if there's no parent.
Quaternion rotation = Quaternion.identity;
if(transform.parent != null)
rotation = transform.parent.rotation;
transform.position += rotation * translation;
break;
}
}
}


This gives you a new overload of transform.Translate to use if you like, with the alternative Spaces enumeration to pass the parent space option.

I haven't tested it extensively to verify whether it handles non-uniform scales the same way the original transform.Translate does, though I'd caution that if you're using non-uniform scale in a parent hierarchy you're likely going to run into bigger troubles. ;)