Search Unity

rigidbody2d.velocity = new Vector2.... // Explain it like I'm 5, please?

Discussion in 'Scripting' started by zeropoint101, Nov 22, 2014.

  1. zeropoint101

    zeropoint101

    Joined:
    Mar 2, 2014
    Posts:
    8
    So I'm new to coding and new to Unity. My question is about understanding how to code, and understanding the concepts and syntax, rather than about how to actually accomplish this behavior. If I want to keep make my sprite move to the right when the game starts, I can do something like this... and please remember, I'm just doing/asking it this way to understand the code. I know it's not the best way.

    void Update ()
    {
    rigidbody2D.velocity = new Vector2(4, 0);
    }

    Here is where I get confused/have questions, and I'm not even sure if I know how to ask properly, so hopefully someone will understand...

    My first thought was, if this is a property of the rigidbody2D component, why can't I just write something like...

    rigidbody2D.velocity = (4,0)

    I'm kind of starting to understand why that doesn't work, but I can't get to a full understanding of it and it's frustrating me.

    Instead of continuing to write a bunch of "what ifs", I'll just leave it at this and maybe someone can help...
     
  2. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    The velocity property of the rb2d requires a Vector2.
    You have to say = newVector2(4,0) so that it can allocate a new piece of memory to hold the 2 values of x and y (its calling the constructor of the vector2 struct, taking 2 float parameters)
     
    davidxxx likes this.
  3. koray1396

    koray1396

    Joined:
    Mar 18, 2014
    Posts:
    10
    okay, for start you should get the habit of using script reference pages. from there you can see that rigidbody2D.velocity requires Vector2. such as transform.position holds a value of Vector3, and transform.rotation is a Quaternion.

    now, the right hand side value type must match the left hand value type. rigidbody2D.velocity is a Vector2, but right hand side is undefined. For now it is ok to know that to declare a Vector2, you should be using new Vector2(...).
     
    davidxxx likes this.
  4. Mystique

    Mystique

    Joined:
    Nov 19, 2014
    Posts:
    40
    Vectors represent lines in space. X = Horizontal, Y = Vertical, that's why after Vector2 (which means 2 Vectors) you have to put ( X coordinate , Y coordinate).

    Velocity is just a force , it doesn't have any defined or known parameters other than force.
    That's why if you put velocity = (4,0), the rigidbody2D doesn't know where the velocity is.
    You have to first define the parameters you want to navigate before you can journey them!



    The reason for this is because unlike Humans the Computer has to be told what parameter it is in before it can change them - otherwise it doesn't know where it is. You must tell the Computer the LOCATION beforehand, and the ACTION afterwards.
    ________________________________________________________________________
    Rigidbody 2D reference page http://docs.unity3d.com/ScriptReference/Rigidbody2D-velocity.html
    Vector2 reference page http://docs.unity3d.com/ScriptReference/Vector2.html


    Like the other guy said, get into the habit of using the script reference page if you don't know how/why to use a code.
     
    Last edited: Nov 22, 2014
  5. sootie8

    sootie8

    Joined:
    Mar 25, 2014
    Posts:
    233
    @zeropoint101
    The short answer is yes you can, except it needs to be written as
    Code (JavaScript):
    1. rigidbody2D.velocity = Vector2(4,0)
    Assuming you turn off drag and angular drag, and set this in the start, it would continue on at a constant velocity.
    The reason for needing the to write Vector2(4,0) as opposed to just (4,0), is that you are passing a full instance of that struct. If you were able to modify a single property of the existing struct (rigidbody.velocity.y which you cannot modifiy), then you would not need to instantiate a new instance.
     
  6. zeropoint101

    zeropoint101

    Joined:
    Mar 2, 2014
    Posts:
    8
    Hi. Sorry for the delayed response. Thank you all for the answers. I've learned a lot since I made this post, and I also didn't ask my question very well. There were two things I couldn't understand...

    The main one was why the "new" keyword was required. I couldn't understand why I couldn't change the velocity property directly, as opposed to creating a "new" one. I've learned since that properties can have "get" and "set" accessors, and that was my biggest confusion. The velocity property does not have a "set" accessor.

    I actually did and do use the script reference pages, but there is a lot of information that just isn't there, like the explanation of get and set, and which properties have which. And being new to coding, those references are useful, but can be confusing.

    The other problem I had was just syntax. If velocity did have a set accessor, then I just wasn't sure of the proper syntax to change the value of a Vector2 type, so I was typing "... = (4,0)" instead of "... = Vector2(4,0)".

    Don't take this rudely, please, considering I was the one originally asking, but what you said actually isn't correct because there is no set accessor.
     
  7. hpjohn

    hpjohn

    Joined:
    Aug 14, 2012
    Posts:
    2,190
    In javascript, it works, because it handles that for you (ie trains bad practices)
     
  8. sootie8

    sootie8

    Joined:
    Mar 25, 2014
    Posts:
    233
    Do you even know why it would be a bad practise, or are you just guessing? By the way if you check the normal Rigidbody class, the velocity property has a public set accessor.
     
  9. zeropoint101

    zeropoint101

    Joined:
    Mar 2, 2014
    Posts:
    8
    Can you be more specific as to what you mean? This doesn't really tell me anything useful for someone just starting to learn...

    Could you address me, the guy who asked the original question, as well? If I'm wrong in saying you are incorrect, then tell me and tell me the how and why, and I'll listen. I just now realized in your original comment that you specified javascript. I've been learning and using C# and that's my fault again for not clarifying that in the OP. However, I put the exact line you suggested into a newly made javascript script and, although I do not get an error, my sprite doesn't move. What's going on here?

    Does the class have a set accessor in javascript, but not in C#? That seems odd, but there's clearly a lot I'm new at here...

    How do I go about knowing if a property has a set accessor? It doesn't have this information in the Unity scripting reference. You said "if you check the normal Rigidbody class.....". How do I check?
     
  10. sootie8

    sootie8

    Joined:
    Mar 25, 2014
    Posts:
    233
    @zeropoint101
    It's actually my bad, I used a normal Rigidbody to test it, where you can set the X,Y,Z variable straight, however, for some reason Unity has changed the Rigidbody2D class to not allow this. To be honest the documentation can get a little sparse on information regarding setters, if you really need to know and it is not listed, then trail and error is the best way. Not a great answer but there you go.

    So to summarize, you might as well use rigidbody2D.Velocity.set(x, y) for Rigidbody2D. Although it is the same as rigidbody2D.velocity = new Vector2(4, 0);

    Ps. Monodevelop / VS does tell you the the availability of a variable with its information promt, it usually says public set: public get, or public set : private get
     
  11. Jack_Fx7

    Jack_Fx7

    Joined:
    Nov 26, 2014
    Posts:
    1
    thank you very much at all
     
  12. zeropoint101

    zeropoint101

    Joined:
    Mar 2, 2014
    Posts:
    8
    Thanks for sticking with me on this. Unfortunately, I'm confused again. Please forgive me if I'm just being dense. I use Visual Studio. I'm not seeing any information prompt that tells me things like "public get, public set, etc..". I understand the intellisense feature and I know that I get hoverover information about various things, but I'm not seeing info anywhere about the get/set or the access level. How do I get to this?

    However, I discovered by experimentation that if I right click on something and choose "go to definition" in the context menu, it will take me to metadata that shows the actual class definition in the UnityEngine namespace. When I checked both Rigidbody and Rigidbody2D this way, the velocity property in both of these has both get and set. The fact that I can't seem to change velocity directly, plus the person who originally explained get and set to me said that velocity had no set accessor... this made me obviously assume it didn't have a set accessor. But it does apparently... but I still can't change it directly without using "new" and creating a new instance, as opposed to just changing the value of the original Vector2 instance of velocity.

    When you said rigidbody2D.velocity.set(x,y) is the same as rigidbody2D.velocity = new Vector2(x,y) ...I think this is the key to what I'm not understanding, and it's probably simple, but how is "setting" the value of velocity the same as creating a new instance?
     
  13. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    You are confused about value types vs reference types. Calling new Vector2() is no big deal, it's not allocating any new heap memory because Vector2 is a Value Type. If it was a Reference Type then I could see your concern.
     
  14. zeropoint101

    zeropoint101

    Joined:
    Mar 2, 2014
    Posts:
    8
    ^^ I'm thinking, maybe, it's because Vector2 is a struct... but
    Yeah, I do think you're right that my problem has something to do with that. I thought I understood all this from another thread in another forum, but apparently I still don't get it. I know that Vector2 is a struct, and that structs are value types, and I've read plenty about value and reference types and I *thought* I understood. My brain is really turning to mush at this point, but I keep thinking something like this...

    int is a value type as well, correct? So if I want to create an int named myBrainHurtsThisMany and give it a value, I don't write

    int myBrainHurtsThisMany = new int(47);

    I just write

    int myBrainHurtsThisMany = 47;

    and when I change the value I just write

    myBrainHurtsThisMany = 112;

    Therefore, if creating a new Vector2(or changing the value of one named velocity), why can't I write

    Vector2 shootMeHere = (4,0);

    or

    rigidbody2D.velocity = (4,0);

    Do you see why I'm getting at? why I'm confused?
     
  15. User340

    User340

    Joined:
    Feb 28, 2007
    Posts:
    3,001
    yes
    wrong (partly). You can indeed write int myInt = new int()... It compiles. It's just that ints are so common that they made something called literals. A literal is a shortcut allowing one to create an object without the whole new object() part. There are literals for ints, floats, strings, and a few more. There AREN'T literals for Vector2 however, because that's a Unity type.
     
  16. zeropoint101

    zeropoint101

    Joined:
    Mar 2, 2014
    Posts:
    8
    Hm.. ok. Well I know, basically, what a literal is. So now that tells me why the syntax is different. From some other stuff I've been reading, I guess the misconception I have is that anytime you declare something with a type and a name, that the data referenced by that name is stored in one or more specific memory locations, and that those locations can always just be "swapped out" with new data, without having to allocate a new memory location, i.e. a new instance with the same name, each time you give that name new data. I'm realizing that's not the case, but I can't wrap my head around why. I think I just need to study a lot more about how and why and where memory is allocated with different types and situations. I know it doesn't really matter for now if I know the right way to do it, but it just interests me. :)