Search Unity

Learning the scripting

Discussion in 'Scripting' started by Sanity11, Nov 25, 2007.

  1. Sanity11

    Sanity11

    Joined:
    Nov 25, 2007
    Posts:
    96
    Hi all!

    I am totally new to Unity. The first time i saw it I was sold. I have even bought a mac for it.

    The interface and all seems very clear.
    The only thing I have to learn as fast as possible is the scripting part.
    Does anybody have some suggestions on how to learn that in a efficient way?

    I allready know vba but I cannot read the Java code that is used in many examples.

    Thanks for the reactions! :D
     
  2. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
  3. Sanity11

    Sanity11

    Joined:
    Nov 25, 2007
    Posts:
    96
    Thanks, Ill dive in to them right away.
     
  4. Sanity11

    Sanity11

    Joined:
    Nov 25, 2007
    Posts:
    96
    Ok, looks great but it doesnt really cover the basics of the programming language. Does anybody know some rescources that I can use?
     
  5. BenH

    BenH

    Joined:
    May 11, 2007
    Posts:
    175
  6. bronxbomber92

    bronxbomber92

    Joined:
    Nov 11, 2006
    Posts:
    888
  7. Sanity11

    Sanity11

    Joined:
    Nov 25, 2007
    Posts:
    96
    Thanks for the tip. I think ill buy it later on.
    I am practicing a little allready.

    I have made a square that shoots balls. Now I want the ball to dissapear when it hits something so i have attached this code to the ball.

    Code (csharp):
    1.  
    2. function onCollisionEnter (collision : Collision) {
    3.     Destroy(gameObject);
    4. }
    5.  
    But this doesnt work for some reason.

    Can somebody tell me what I am doing wrong.

    btw: I got this from the tutorial.
     
  8. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Code (csharp):
    1. function onCollisionEnter
    2.  
    Watch your case. (OnCollisionEnter vs. onCollisionEnter.)

    --Eric
     
  9. Sanity11

    Sanity11

    Joined:
    Nov 25, 2007
    Posts:
    96
    :oops:
    Thanks!
     
  10. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    If you do get "JavaScript: The Definitive Guide" (excellent book!) or any other JavaScript reference, be aware that Unity's JavaScript is significantly different from JavaScript.

    (Aside: is this documented properly somewhere?)

    Off the top of my head:

    1) Unity JavaScript is compiled (and fast, which is excellent) but not so dynamic as JavaScript in browsers (which is interpreted).

    2) You can, and generally should, explicitly declare variables as having types (helps code to run faster, detects some errors at compile-time -- which is excellent, and others at run time -- which is less excellent).

    2a) You can (and often should) explicitly scope variables as private, static, etc.

    2b) Unity will implicitly type a variable if you assign it a value when you declare it. So:

    var a = "fred"; // a is now of type String
    a = 5; // ERROR! -- a is a String
    var a : String = "fred"; // redundant

    But:
    var a; // a is dynamically typed;
    a = "fred"; // works
    a = 5; // works

    3) Method names are generally capitalized, except when they aren't. (It's confusing.) Basically, Unity's JavaScript is living in a .NET naming convention world (where methods are CamelCase and properties are camelCase), but is also trying to be like JavaScript (which, like C, is strongly biased towards lowercase and camelCase for everything).

    4) JavaScript has, in essence, three types: number, string, and Object (with arrays in essence being Objects). Unity's JavaScript has many more types, including:

    Objects, which are NOT interchangeable with arrays, or Arrays (which are somewhat like JavaScript's objects, but not dynamic)
    var a = new Object(); // works
    a.fred = "wilma"; // runtime exception!

    native arrays (which are not associative or dynamic)
    var a = [1, 2, 3];
    a.Push(4); // ERROR -- won't work!

    Mono Arrays (which are associative and dynamic, but not with the same syntax sugar as Objects)
    var a = new Array();
    a.Push(4); // This works

    integer types (including int, uint32, etc.)
    float
    And Unity's many built-in classes (e.g. Vector3)

    5) It's important to understand that when you write a behavior script in JavaScript you are actually writing a class implementation, where:

    a) The name of the class is the name of the script file (so if it's foo.js you can instance it elsewhere by saying var x = new foo()).

    b) Certain "magic" method names will in fact implement event handlers (e.g. Start(), FixedUpdate() etc.). In any event, a function declaration is a method of the class you've written/

    c) Code written outside function definitions inside your file are executing in the class's body. Variables declared in it are members of the class.

    d) static functions and variables in a class are, in essence, class functions and variables.

    This is all FAR more elegant than implementing classes in "real" JavaScript, but also somewhat restrictive ... mostly in a good way (you can't arbitrarily wire objects together the way you can in "real" JavaScript).

    6) Unity 1.5 (?) and earlier did not support JavaScript switch() statements, but Unity 1.6.x and later do. Yay!

    6a) Unity 2.x supports eval() -- possibly only in the dev environment (?). Don't use eval :)

    7) Semicolons are generally optional in JavaScript (which has some ferocious logic to determine when a statement ends) but very much not optional in Unity.

    If I'm wrong or out of date -- please correct me. If there isn't a definitive document out there explaining all this, there really ought to be one.

    Scripting errors will show in Unity as a "red x icon" in the window status bar. Click on the icon to bring up a list of errors, which should be both informative and lead you to the line in the script that caused the problem.
     
  11. Sanity11

    Sanity11

    Joined:
    Nov 25, 2007
    Posts:
    96
    Thanks! I am going to print this so I can use this as a reference.
     
  12. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    This is only true if otherwise you'd have dynamic typing, which isn't that common. Generally Unity's type inference takes care of that for you. For example, var foo = "blah"; and var foo : String = "blah" are exactly the same. They are both statically declared as a String, and you gain nothing by writing it out.

    This is unlike regular Javascript, where everything is dynamically typed. You can write "var foo = "5"; var bar = foo * foo;" in regular Javascript, and bar will equal 25. You can't do that in Unity, though, since you can't multiply strings. To get the same result in Unity, you'd have to do "var foo = "5"; var bar = parseInt(foo) * parseInt(foo);".

    I'm sure you know that; I'm only saying so because Unity's type inference seems to be commonly misunderstood. Most often, I only bother to declare types if I'm dealing with ints/floats, since it's possible for the code to get wonked if you change them accidentally. For example, if I just say "var foo = 5.5;" and later change that to "var foo = 5;", then it becomes an integer, which is probably not what I wanted. I could say "var foo = 5.0;" and it would remain a float, but I don't always remember to do that. ;) So it's safer to say "var foo : float = 5.5;"...that way it will always be a float no matter what.

    It doesn't hurt anything to declare types yourself, of course, but personally I find that the less stuff in the code, the easier it is to read. So just saying var foo = "blah"; is better for me, since the quotation marks make it patently obvious that it's a string. Likewise, var foo = Vector3(1, 2, 3); is even more obviously a Vector3, so there's no point whatsoever in writing var foo : Vector3 = Vector3(1, 2, 3);.

    If you always declare the type, then you can be 100% sure you're never using dynamic typing, but you can more easily do that by using "#pragma strict" at the top of your scripts. This way, if Unity can't figure out the type, then you'll get a compiler error, so you'll know you have to declare the type in that case.

    1.x did have switch(). 2.0 added eval(), however, which wasn't in 1.x. (Though it only works in the editor as far as I know, but I'm not real familiar with it anyway.)

    --Eric
     
  13. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    switch was definitely not in every 1.x ... but thanks for clarifying that. I think in 1.5.x I ended up having to rewrite a bunch of code to avoid using switch().

    As for your earlier point:

    declaring:

    var x : String; // worth doing
    var x : String = "fred"; // redundant

    I didn't realize that -- worth knowing.
     
  14. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    You're right...switch was actually added in 1.5, but since that's when I started using Unity, from my point of view it's been there forever. ;)

    Yeah, it was months before I understood Unity's type inference, but then it wasn't really mentioned in the docs much at the time (better now), and I was probably laboring under the "Javascript = dynamic typing" misapprehension, as it applies to Unity anyway. Basically, Unity internally declares the type for you. (Except when it doesn't. ;) )

    --Eric
     
  15. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    Right -- I did some quick experimentation, verified what you said, and then modified my big post accordingly.
     
  16. lgoss007

    lgoss007

    Joined:
    Dec 6, 2006
    Posts:
    88
  17. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    The problem with those articles is that they jump from language to language, and start at way too low a level for many people, and never get deep enough to be useful. They're also kind of confusingly written -- ranging from...

    Comp Sci jargon with no real content:
    "JavaScript uses dynamic typing, meaning data doesn't always have to declare a type."

    To folksy to the point of being wrong:
    "A block '{ }' allows multiple statements to be written where one is allowed."

    To ... huh?:
    "Scope is defined in a block, remember those? Also remember that a block can be nested in another block. A nested block inherits all of the variables inside it's (sic) parent block, but the parent can't redefine a variable that's declared in a child. And when variables go out of scope they are no longer defined."

    Documentation, above all, needs to be user-centric. Very few users will want to learn two or three languages at the same time. Since splitting stuff into separate pages is cheap (i.e. free) and user attention span is expensive, writing separate articles covering one language at a time would be a good start.

    Telling someone that:

    function spam(){
    { ; ; }
    }

    is legitimate code is about as useful as telling someone that you can safely operate a car by sitting in the back seat and not turning on the engine.

    Again -- documentation needs to be user centric. There are three major kinds of users Unity docs need to address:

    1) Folks with little/no coding experience, who need to learn how to program. Confusing folks like this with multiple languages and unrealistic abstract examples is useless.

    2) Folks with significant coding experience who don't know Unity's version of JavaScript or its API/library function or IDE. Again, these people don't need to know that { ; ; } is a legitimate block of code.

    3) Folks who know how to code in Unity, but need specific information on a specific topic (e.g. how do I change the color of some text?).

    It's very important not to confuse your target audiences, or to try to write a document for more than one audience at a time.

    Unity's documentation does a very good job for the third audience (if it transparently wrapped in Mono and language documentation, it would be fantastic).

    I remember that at some point Macromedia reorganized Director's big Lingo reference putting everything in alphabetical order rather than sorting functions and objects into chapters first. If I am looking up a function because I don't know how to use it or what it does, the last thing I need is a book that requires me to guess which chapter it might be in first.
     
  18. aaronsullivan

    aaronsullivan

    Joined:
    Nov 10, 2005
    Posts:
    986
    Keep in mind those pages were done by a Unity user volunteering his time and energy to add something to help out.

    Also, it's a wiki. Improving it is more valuable than critiquing it. :)

    Great summary of the differences, though, podperson. That should go on the wiki after a little clean up. Something like, Javascript vs. Unity Javascript.
     
  19. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
  20. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Cool...I was going to suggest that be on the wiki. Though switch was definitely in 1.5, not that it matters much. (I know it's a wiki, but I don't really like messing with other people's stuff....)

    --Eric
     
  21. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    Made the relevant change.
     
  22. lgoss007

    lgoss007

    Joined:
    Dec 6, 2006
    Posts:
    88
    Yep, thanks! :D

    Thanks for the... suggestions (criticism :p), others have expressed some similar concerns. I'd like to update it some day but currently I'm doing contract work along with a normal day job and I'm in a play... so time is not on my side.

    To be fair, that's in the recap where dynamic typing, data, declare, and type were already defined. Recaps should only be a reference to use once you understand the concepts involved in the chapter.

    Oops, kind of left something out there. I agree it needs to be better defined.

    Well it is explained in the example, but yeah that phrasing could be confusing.

    This was something others suggested and I may do (when time permits). Some arguments why it was done this way are below.

    Except the example is true, while your example is false. It would be more like telling someone there is an airbag in your steering wheel... probably won't ever use it, but sometimes you're blind-sided by people doing crazy things :wink:

    OK but yeah, not a great example.

    This was the intended audience... mostly.

    Audiences kind of overlapped. :oops:

    But I see benefits on both sides. At the time people were asking how to program. But at the same time it seemed quite a few of them wanted to know how to translate a script from C# to JavaScript or vice-versa.

    I put them together because learning a language isn't the key part, learning the concepts of the language is far more important. When I learned to program I learned both Basic and Pascal together, and both of those are far more different than C# and JavaScript. :eek:

    And the abstract examples were probably a little extreme. From my experiences though, a lot of beginners try to take on too much at once without learning a solid foundation, and a lot of tutorials overwhelm them.

    Yes it could be better, thanks for the comments. :D
     
  23. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    First of all -- no offense intended. It's great that you wrote this tutorial, and I'm sorry I came across as way too harsh.

    I think you're simply using a different meaning for the word "operate". In both cases you cause no errors, misuse no equipment, yet achieve nothing.

    This is yet a third audience.

    If learning a language isn't the key part, then learning two languages at once is definitely not the key part.

    If you look at almost any good book trying to explain X, but needing to discuss Y at the same time (e.g. how to use MySQL -> X, which tends to involve programming in some language -> Y) the author will generally figure out a way of NOT explaining multiple instances of Y while trying to explain X. The obvious option is to pick the most common or popular instance of Y and only occasionally mention other cases. Or even name the book at "Doing X using Y".

    I think that was my original point.

    What I would do is take the article, tear out everything to do with C#, either loosen or tighten the prose as appropriate. I'd also make sure that there's a summary and recap that match the content and map onto each other (e.g. a bullet point in the recap corresponds to a heading / subsection in the body).

    Later, if you want an equivalent article for C#, take that article, and replace all the JavaScript with C#.

    Finally, if you're going to try to be rigorous, be correct. An assignment statement assigns the VALUE of an EXPRESSION on the RIGHT to the VARIABLE (or property) on the LEFT. A variable is a SYMBOL that is used to refer to a VALUE which can change. (A constant is a SYMBOL used to refer to a VALUE which cannot change.

    A ";" isn't a statement, it's a statement terminator. It turns an arbitrary wodge of text (including an empty string) into a statement, it isn't of itself a statement. (It's also the reason that the syntax of for() loops is so infuriating.)

    The reason for rigor is that it's powerful and unambiguous. A common mistake when trying to explain complex abstract domains (e.g. computer programming languages) is to adopt the style and jargon of stuff you've read in that domain without understanding the correct use of it.
     
  24. podperson

    podperson

    Joined:
    Jun 6, 2006
    Posts:
    1,371
    Added more notes on Unity vs. JavaScript:

    Math.abs() -> Mathf.Abs()

    var foo = function(){} // not allowed in Unity
     
  25. lgoss007

    lgoss007

    Joined:
    Dec 6, 2006
    Posts:
    88
    Thanks for the tips... and for your contribution as well!
     
  26. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I just realized, this part isn't correct:

    That doesn't generate an error in Unity; you don't have to declare variables before using them. (But it's still good practice.)

    --Eric