(Adapted from Bond, p. 483.)
Suppose you have a Unity GameObject obj and want to set its x position to 5.
You'd like to say:
obj.transform.position.x = 5;
but this doesn't work!
The reason is that position is a property, so obj.transform.position returns a new Vector3, not the one stored in the transform.
You therefore have to do this:
pos = obj.transform.position;
pos.x = 5;
obj.transform.position = pos;
This bothers me because you can't tell by looking at something whether it's a field or a property. .position is accessing a property, but .x is accessing a field.
@peterdrake That's not quite accurate. It's because position is a property *and* a struct. This is actually a C# thing moreso than a Unity thing. You can change members of class properties or struct variables just fine. Unity made the choice to have core math structures like Vectors and Quaternions be structs, presumably to impart a degree of immutability.
@LouisIngenthron I think that makes sense.
If I understand correctly,
obj.transform.position.x = 5;
is effectively expanded into:
Transform t = obj.transform;
Vector3 p = t.position;
p.x = 5;
The first assignment (=) makes an alias, because a Transform is an object.
The second assignment makes a copy, because a Vector3 is a struct. This is the hidden culprit.
The third assignment technically "copies" the 5, but since it's an immutable primitive value, that doesn't matter.
If this is accurate, would the same thing happen if position was a field rather than a property?
(It may also be that the "getter" for position creates a new Vector3 for more complicated reasons involving global vs local positions, which seems like it would create this problem even if a Vector3 was an object rather than a struct. If that's true, my original complaint about properties holds.)
I'm guessing Unity made Vector3 and Quaternion structs for efficiency reasons (to avoid a level of indirection), but I don't know. It *might* be the right choice given Unity's goals, but it feels like another of the many, many gotchas in Unity.
Thanks -- this is very helpful!