Why can I modify transform.position but not transform.position.y?

I am trying to write this:

        transform.position = distanceBetweenCamAndPlayer + player.transform.position;
        transform.position.y = cameraY;

the first line works fine, but the second one displays the error: “cannot modify the return value of transform.position because it is not a variable”.
How come I can change the transform.position with a vector3 but I can’t change only the Y component?

Because of value types!

A Vector3 is a value type, which means that it’s passed by value. So whenever you grab a Vector3 from somewhere, you’re grabbing a copy:

Vector3 a = new Vector3(1, 2, 3);
Vector3 b = a;
b.x = 15;
Debug.Log(a.x); //still 1!

Since Transform.position is implemented as a getter, you’re getting a copy whenever you’re retrieving it. So when you do:

transform.position.x = ...

You’re trying to set the x-value on a copy of the transform’s position. The compiler disallows it, since you’d otherwise have code that does nothing that looks like it does something.

You’ll either have to get a copy, modify that, and pass it back in:

var pos = transform.position;
pos.y = cameraY;
transform.position = pos;

Or make an extension method for Transform that allows you to do what you want:

public static class TransformExtensions {
    public static void SetYPos(this Transform t, float newYPos) {
        var pos = t.position;
        pos.y = newYPos;
        t.position = pos;
    }
}

//your code above can now be:

transform.position = distanceBetweenCamAndPlayer + player.transform.position;
transform.SetYPos(cameraY);
6 Likes

I used to assign Vector.3 parameters of other classes so I think that example doesn’t quite fit. If position would not be a property then transform.position.x = 2 will not create a new position but assign x directly.

So getter is the reason for that here, but thanks for that explanation.

Plz,read about difference between class and structure

You can change the value, but you have to change all of them because it’s a vector3.
transform.position = new Vector3(transform.position.x, cameraY,transform.position.z);

Take a look at the source code for Transform:

public Vector3 position
{
   get
   {
     Vector3 result;
     this.INTERNAL_get_position(out result);
     return result;
   } 
  set
  {
     this.INTERNAL_set_position(ref value);
  }
}

transform.position gives you a copy of the position. Writing to transform.position.x would do nothing useful.

1 Like