Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is Vector3 implemented, why are the properties readonly?

Vector3 v = new Vector3(1, 1, 1);
v.x = 5;

Why can't I do this? I have to do v = new Vector3(5, v.y, v.z);

I assume the reason behind this is for performance. But I can't guess at why this is necessary.


Edit:

I lied, this actually does work. The Vector3 I've been working with transform.position always returns a copy of itself, which is why setting values on it doesn't work. Some kind of Unity magic.

like image 956
Farzher Avatar asked Feb 16 '23 07:02

Farzher


2 Answers

I lied, this actually does work. The Vector3 I've been working with transform.position always returns a copy of itself, which is why setting values on it doesn't work. Some kind of Unity magic.

Actually, the reason is that Vector3 are structs. In C#, structs are value types. So they are always returned by value wereas class can be pass/returned by references. It will be the same behaviour for all properties that wrap struct members (like Rect, Vector2, etc...)

As this is a property, the get method return a copy value of the struct position when you call it. You will always need to assign it to a local ref, modify it and then reassign it:

Vector3 t_Pos = transform.position;
t_Pos.Normalize();
transform.position = t_Pos;
like image 82
jeerem Avatar answered Mar 07 '23 22:03

jeerem


Unity doesn't allow direct access to Transform.position because position is derived. In other words, internally Unity is storing a transformation matrix, so when you get the position, it's grabbing a copy of it from the transformation matrix.

So it probably looks a little like this for position:

public class Transform
{
    public Vector3 position
    {
        get
        {
            // it would be this if the matrix itself is in world space
            return new Vector3(matrix.m30, matrix.m31, matrix.m32);
        }

        set
        {
            // it probably doesn't use these mono bindings, but
            // I'll use them here for this example
            matrix.SetRow(3, new Vector4(value.x, value.y, value.z));
        }
    }
}
like image 41
weatx Avatar answered Mar 07 '23 20:03

weatx