- Home /
Using var as a placeholder for velocity... why?
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;
temp.y=3;
rigidbody2D.velocity = temp;
Why is this necessary? I've tried going with rigidbody2D.velocity.y=3;
instead, but it won't compile.
Answer by NoseKills · Jan 10, 2015 at 06:09 PM
It's because 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.
If rigidbody2D.velocity only returns the value of the Vector3, why does this line work?
rigidbody2D.velocity = temp;
Read about properties. They are specially written so you can Get the entire value, or Set the entire value, and nothing else. When you use = with a property, it automatically runs the Set function.
This is kinds of an "oops" for C#. $$anonymous$$ost people say "yeah, C# is broken that way, but don't don't make velocity like that. Unless you're making a game or something where speed matters."
@brentshermana because properties have different logic for "setting" and "getting".
public SomeStruct velocity
{
get { return vector; }
set { vector = value; }
}
If you do velocity.y = 2
, you are first using the "get" part of the property to get a copy of the vector and then accessing the y component in it.
if you do velocity = Vector3.zero
you are assigning directly to the property using the "set" part of it. The value
becomes a copy of your vector with your values and that copy is assigned to the internal vector in the struct.
Answer by Owen-Reynolds · Jan 10, 2015 at 06:32 PM
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>4) vel.y=4;
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.)
Your answer
Follow this Question
Related Questions
Problem Trying to Apply Non-Kinematic Velocity to Rigidbody 0 Answers
Need help with scripting bug fix. pleease 0 Answers
C# RotateAround for 2DRigidBodies 1 Answer
c# syntax ((float>0)?(1):(2)) 2 Answers