I’m working through a few Unity tutorials to get my feet wet with C# scripting, and I came across this:
var temp = rigidbody2D.velocity;
rigidbody2D.velocity = temp;
Why is this necessary? I’ve tried going with
rigidbody2D.velocity.y=3; instead, but it won’t compile.
rigidbody2D.velocity is a property, not a direct reference to a Vector3 inside the Rigidbody2d class.
Because Vector3 is a struct, not a class, and therefore a value variable, not a reference variable, the property
rigidbody2D.velocity actually gives you a new Vector3 with the same values as the actual Vector3 inside the rigidbody instance. If you’d change the x,y,z values of the Vector3 returned by the property, you would change this new copy of the vector and the actual vector inside the rigidbody would remain unchanged.
The reason it has to be done that way is boring technical junk. The important thing is that, yes, it does need to be done that way. Almost anytime you “reach through” an object to a small multipart item, it needs to be pulled-out, changed, then put back.
But that’s often what you want to do. Say you wanted to do more with velocity. It’s nicer-looking (and not any less efficient) to avoid typing the long name every time:
Vector3 vel=rigidbody.velocity; // pull out
if(vel.y<0 && antiGrav==true) vel.y*=0.5f;
if(vel.magnitude<0.1f) vel=Vector3.Zero; // fake friction
rigidbody.velocity=vel; // put back
And Unity has some shortcut functions for common changes.
The exact rule is, whenever you have a struct, you can’t “reach through” most things. Structs are some built-ins: Vectors (position, velocity,) Color, rotation. Your scripts are classes, so
A.getComponent().hitpoints is still fine.
The exact exact reason (I think) is that most members are really getters/setters. dot-velocity is really a C#
get. And C# has some funny rules about gets and structs (you can read about them, but it’s boring. You can also read about why some people think designing C# that way was just a bad idea.)