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
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 is different, including access and type specification:
Variables with dynamic type resolution
Performance is slower with dynamically typed variables, and you can run into casting problems. Iif this is a concern, use
Multi-dimensional array declaration
Character literals not supported
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
Limited interface support
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.
The New keyword
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
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.
For a good explanation of how Coroutines and the main routine interact, see Duck's Answer
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.
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 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.
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).
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.
answered Mar 13 '10 at 12:12 AM
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.
answered Mar 11 '10 at 06:22 PM