|
Although the Unity Scripting page gives an overview of the differences in C# versus Javascript, it isn't comprehensive. I have run into several places where a tutorial in Javascript had some code that didn't translate directly into C#, and I had to do some research to find the C# version. So what other syntax differences are in C# versus JS?
(comments are locked)
|
|
The purpose of this answer is to provide a single point of reference for the syntactical differences between C# and JS. It is mainly for people who have already made their decision as to which language to use, and might need to know the differences (for instance, to translate a script from one language to another). If you want to know more about why you might choose one language over another in Unity, there are several other Questions - for instance: How should I Decide... C#/JS/Boo. And for performance issues, there is: Performance Difference... JS/C#?. These are in addition to the differences listed in the Unity Manual page: Writing Scripts in C#. Unity Script Directives Unity has a number of Script Directives, for example, AddComponentMenu. The syntax is:
Type names A couple of the basic types are spelt differently in pure Unity C#:
However, if you include System in your C# script, you can also use .NET's String and Boolean class (note the upper-case):
Variable declaration Variable declaration is different, including access and type specification:
Variables with dynamic type resolution In Javascript only, variables can have an unspecified type. This only occurs if you do not assign a value while declaring the variable. For example:
Performance is slower with dynamically typed variables, and you can run into casting problems. Iif this is a concern, use Multi-dimensional array declaration Unity's Javascript support the syntax for declaring multi-dimensional built-in arrays. Eg:
The performance of multi-dimensional arrays, at least in Javascript, is questioned. Character literals not supported Unity's Javascript seems to be missing the syntax to declare character literals. This means you need to get them implicitly by referencing a character index from a string. For example:
Class declarations You can define classes in Javascript, in a similar way to C#. Here's an example of a class which inherits from MonoBehaviour
However in Javascript, if you're inheriting from MonoBehaviour, you don't need to write a class body at all (see the next section). You can also write classes which do not inherit from anything, however you can't place scripts like this on Game Objects - you have to instantiate them with the 'new' keyword:
If you are inheriting from MonoBehaviour, you should not use constructors or destructors. Instead, use the Event handler functions "Start", "Awake" and "OnEnabled". Implicit Class declarations Unity's Javascript has a feature whereby if you do not declare any class body, it is automatically implemented for you. For example, a script which contains only variables and functions (and no explicit class declaration) is automatically implemented as:
This means that any Javascript script that you write without an explicit class body, automatically inherits from MonoBehaviour, and is therefore a component which can be attached to a GameObject (which is usually what you want!). Limited interface support While Unity's Javascript does support inheritance and interfaces, it has the very limiting caveat that you can either inherit your class from an existing class, or declare one interface. Eg:
Generics The C# syntax supports "Generics" which allows you to use classes and methods which do not specifically declare a type. Instead, the type is passed as a parameter when calling the method or instantiating the class at runtime. These now work in both Unity and Unity iPhone (since v1.6). .Net comes with some useful Generic classes such as the List and Dictionary, and Unity's own API has some generic functions which remove the need for some of the verbose casting which would otherwise be necessary in C#. For example:
For a more complete definition of Generics: MS Introduction to C# Generics The Foreach keyword C# Iterators use foreach instead of for. Also notice the variable declaration within the for/foreach statement. C# requires the type of the item contained in the list to be explicitly declared.
Note though that the JavaScript version uses inefficient dynamic typing (since you *can't* declare the type). The static-typed alternative is:
The New keyword In Javascript, you can create a new instance of an object or struct without using the 'new' keyword. In C#, using "new" is mandatory.
Yield in Unity C# versus Unity Javascript Although Unity's documentation does (briefly) cover the syntax differences in using Yield at Writing C# Scripts(Step 4), there is also a Unity Answer that covers How do I Use Yield in C#, which has a more detailed explanation. In addition, the answer by equalsequals has a link to a Coroutine Tutorial that is worth checking out. Unity's Yield has additional capabilities over .NET C# Yield The above paragraph covered the differences in Unity's C# versus Javascript syntax. However, I think that it's worth explaining that the behavior of Unity's Yield statement (in both C# and Javascript), has some additional features not in Microsoft's .Net C# behavior. Basically, Unity has added the YieldInstruction (and child classes such as WaitForSeconds) to Yield. These classes give Yield the ability to temporarily pause the function, until a condition is met. If it has zero parameters, it pauses for a single frame. If it has a parameter of WaitForSeconds:
then it pauses for some number of seconds. If the parameter is another Coroutine, then it pauses until that Coroutine finishes. Yield only works this way inside a Coroutine. To start a Coroutine in C#, you use StartCoroutine, whereas it is automatically called in Javascript. For a good explanation of how Coroutines and the main routine interact, see Duck's Answer Casting Javascript automatically casts from one type to another, where possible. For example, the "Instantiate" command returns a type of "Object":
Also, see Murcho's answer for more information about casting, including why you would want to use the second casting method listed. Properties with Getters/Setters In C#, it is possible to define special functions that can be accessed as if they were variables. For instance, I could say foo.someVar = "testing";, and under the hood, there are get and set functions which process the argument "testing" and store it internally. But - they could also do any other processing on it, for instance, capitalizing the first letter before storing it. So you're not just doing a variable assignment, you're calling a function that sets the variable, and it can do - whatever functions do. I'm not going into the syntax here, this answer is long enough :) But here are two links: Changing struct properties / by value vs by reference This is actually a bit more than a syntactical difference but nevertheless fits here quite well: The following code does work in JavaScript/UnityScript but not in C#:
The reason is because transform.position really is not just a public variable but a property, so it's actually returned by a method call - and that happens "by value" for structs (Vector3 is a struct and not a class - for performance reasons). So, to achieve the same in C#, you have to write:
While this may look more complicated (and less performant), it's exactly what also happens in UnityScript - only that in UnityScript, you don't see it. Function/Method definitions First of all, terminology - Javascript uses the term "Function", while C# calls these "Methods". They mean the same thing, and most C# coders understand the term "Function". Javascript functions are declared with the keyword function before the function name. C# Method declarations just use the return type, and the method name. The return type is often "void" for common Unity events. Javascript functions are public by default, and you can specify them as private if required. C# methods are private by default, and you can specify that they should be public if required. In Javascript, you can omit the parameter types and the return type from the declaration, but it's also possible to explicitly specify these (which is sometimes necessary if you run into type ambiguity problems). Javascript function examples:
And the equivalent C# methods examples:
If you want to add any more answers to this question, please do so as an edit to this question (that's what community wiki answers are for). and this answer should be a community wiki as well..
Mar 12 '10 at 09:40 PM
Lipis
But, but, I don't get any points for Wiki posts... :) Just kidding - consider it done. Since it's... done. I added a page to the Programming->General section.
Mar 12 '10 at 11:30 PM
Cyclops
Yeah yeah.. but this questions smells for wiki.. you had that in your mind I would guess before posting it.. :)
Mar 13 '10 at 12:05 AM
Lipis
@Lipis, when you said wiki, I thought you meant putting a post in the Unify Wiki. What exactly does it mean that this post is a Community Wiki? Who changes these things? And then there's the fact I don't get rep points for it any more...
Mar 14 '10 at 11:36 PM
Cyclops
In Java primitive type and their object counterpart are different, but in C# this is all the same : the same IL assembly code is generated.
Apr 14 at 05:26 PM
Kryptos
(comments are locked)
|
|
I'd just like to add to the casting section, in C# there are two types of casts that produce different results when failed.
If the return value of Instantiate() can't be cast to a GameObject, these two lines will produce very different results. The first line will throw an exception, and if not handled correctly with a try catch statement can cause all kinds of issues. The second line however is a much safer way to work. Using the as keyword for casting will return null if the return value of Instantiate() can't be cast to a GameObject. This is a very important difference as you can use this in a couple of ways. 1. It won't throw an exception, so a quick null test is all thats required. 2. Used in a different situation, it can be helpful for determining inheritance hierarchies. E.G. Say you have a base Actor class, and you also create a Player class, a Monster1 class, and a Monster2 class that all inherit from the actor class. Every time you attack and hit something, you want to cause an effect to all actors, however each special actor type requires a different action. By using the as casting method, you can get through this very quickly.
Using the other casting method would cause all sorts of exceptions, and wouldn't actually make any sense here. Cool, thanks, that's very good to know. I was aware of the other casting method, but didn't realize how differently its error-mode worked. I added the info about it to the wiki.
Mar 13 '10 at 02:14 AM
Cyclops
Sep 28 '11 at 02:09 PM
TSorbera
(comments are locked)
|
|
as what you said it seems that you know C#. ok 1 js is a dynamic language so you don't need to cast returned data of functions like instantiate but you need to cast them in C#. 2 when using functions that have a parameter of type "type" like getComponent, you should pass the type of the data that you want. (typeof() or as keyword) 3 structures are passed by value in C# so you can not change the x or y value of a Vector3 and you need to create a new Vector3 and assign it to the Vector3 that you want. in js they write.
in C# you should write
the code is not slower because the js compiler do this itself. this code is not optimized. when you want to use things like transform much in Update or other functions that they run several times. store the result of transform in a variable and use that var instead of calling transform. for example
see the game optimization video of unite 07 for more info. transform or rigidbody or other variables like this will search for the Transform or Rigidbody component and it's not fast. so put them in class scope private vars and use them. @Ashkan good catch on the iPhone 1.6, I didn't realize it had changed. The License page hasn't been updated with that fact. As for the rest, I'm not saying JS is slower than C#, there's already a Question about performance differences between languages. All I'm doing here is listing the syntax differences.
Mar 11 '10 at 06:41 PM
Cyclops
@cyclops many of the things that i wrote were syntax differences but as a programmer i always think and talk about performance. think of a guy that want to choose between languages and see this question and it's answers here. i love cyclops in X men. :)
Mar 13 '10 at 05:13 AM
Ashkan_gc
@Ashkan, actually I picked Cyclops from the Greek mythology, I never read the X-Men comic books (although of course I saw the movies). As to the performance, sure it's a factor, but again, I was trying to focus the Answer on syntax, as there are other Questions about performance. So this Answer is more for someone who has already decided to use C#, and needs to know how to convert the JS-based tutorials, for example.
Mar 13 '10 at 03:00 PM
Cyclops
(comments are locked)
|

I think this question should be a community wiki.
Uh, why? It doesn't even have a single up-vote... It's clearly useless, in fact I should probably delete it. :)
Actually, I've decided my next Question will be, "How to write an MMO for the iPhone while rotating an object/the camera around." It should get millions of votes...
I think it's a good question. I think it's just the answer which should be CW.
+1 @Cyclops Even though I don't like C#.. 600++ :)
@Lipis - dude! heh... Really, it's not my favorite language either - Python is amazing. But for working with Unity, it just seems that C# is the best choice for me.