What are the Syntax Differences in C# and Javascript?
Asked Answered
H

6

0

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?

Houdini answered 6/6, 2023 at 2:38 Comment(5)

I think this question should be a community wiki.

Battery

I think it's a good question. I think it's just the answer which should be CW.

Cholecalciferol

+1 @Cyclops Even though I don't like C#.. 600++ :)

Battery

http://files.m2h.nl//js_to_c.php

Metopic

"back porting"?! ::sputters:: ... but ... oh .. ::clicks download:: Thanks again, Adam!

Abarca
H
0

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:

// Javascript example
@script AddComponentMenu ("Transform/Follow Transform")
class FollowTransform extends MonoBehaviour {
}  

// C# example:
[AddComponentMenu("Transform/Follow Transform")]
class FollowTransform : MonoBehaviour {
}

Type names

A couple of the basic types are spelt differently in pure Unity C#:

  • C#: bool, Javascript: boolean
  • C#: string, Javascript: String

However, if you include System in your C# script, you can also use .NET's String and Boolean class (note the upper-case):

using System;
String foo = "testing";
Boolean bar = false;


Variable declaration

Variable declaration is different, including access and type specification:

// C#: the type is always stated when declaring a variable:
public int myPublicInt = 1;      // a public var
int myPrivateInt = 2;            // **private** access is default, if access is unspecified
public GameObject myObj;         // a type is specified, but no value assigned

// Javascript - type specification is not necessary:
var myPublicInt = 1;             // **public** access is default, if unspecified
private var myPrivateInt = 2;    // a private var
var myObj : GameObject;          // a type is specified, but no value assigned (see below)


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:

// Javascript:
var numBullets : int;  // statically typed (because type specified)
var numLivesLeft = 3;  // statically typed (because type is inferred from value assigned)
var player;            // dynamically typed (because neither a type or value is specified)

Performance is slower with dynamically typed variables, and you can run into casting problems. Iif this is a concern, use `#pragma strict`.


Multi-dimensional array declaration

Unity's Javascript support the syntax for declaring multi-dimensional built-in arrays. Eg:

// C#:
int[,] = new int[16,16];  // 16x16 2d int array

// Javascript:
var a = new int[16,16];

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:

// C#
char myChar = 'a';

// Javascript:
var myChar = "a"[0];  // implicitly retrieves the first character of the string "a"


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

// Javascript example
class MyClass extends MonoBehaviour {

    var myVar = 1;

    function Start() {
        Debug.Log("hello world!");
    }
}  

// C# example:
class MyClass : MonoBehaviour {

    public int myVar = 1;

    void Start() {
        Debug.Log("hello world!");
    }
}

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:

// Javascript example
class MyClass {

    var myVar = 1;

    // constructor:
    public function MyClass() {
        Debug.Log("hello world!");
    }
}  

// C# example:
class MyClass{

    public int myVar = 1;

    // constructor:
    public MyClass() {
        Debug.Log("hello world!");
    }
}

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:

// Your javascript is converted to (approximately)
class TheScriptName extends MonoBehaviour {
     ... your script here
}

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:

// C#
class Apple : MonoBehaviour, ICollectable, IEatable, IThrowable { ... }

// Javascript - only one allowed:
class Apple extends CollectableObject { ... }

// or
class Apple extends IThrowable { ... }


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:

// In Javascript, the "GetComponent" function returns an object, which is automatically cast by Javascript to the correct type
var someScript : ExampleScript = GetComponent(ExampleScript);

// In C#, without the Generic version of "GetComponent" we'd have to cast it ourselves (yuck):
ExampleScript someScript = (ExampleScript) GetComponent(typeof(ExampleScript));

// But instead, we can use the generic version provided by the Unity API, like this:
ExampleScript someScript = GetComponent<ExampleScript>();

// The generic version can also be used from JavaScript:
var someScript = GetComponent.<ExampleScript>();

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.

// Javascript
for (var item in someList) {
    item.DoSomething();
}

// C# 
foreach (ItemType item in someList)
{
    item.DoSomething();
}

Note though that the JavaScript version uses inefficient dynamic typing (since you can’t declare the type). The static-typed alternative is:

// Javascript
for (var e=someList.GetEnumerator(); e.MoveNext();)
    e.Current.DoSomething();


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.

// Javascript:
var myPosition = Vector3(0,0,0);
var myInstance = MyClass(); // creates a new instance of script "MyClass".
var myTex = Texture2D(128,128); // creates a new texture2d object.

// C#
Vector3 myPosition = new Vector3(0,0,0);
MyClass myInstance = new MyClass();
Texture2D myTex = new Texture2D(128,128);


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:

yield return new WaitForSeconds (2.0f); // pauses for 2 seconds.

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":

// in Javascript, there's no need to cast the result of "Instantiate" provided the variable's type is declared:
var newObject : GameObject = Instantiate(sourceObject);

// in C#, both the variable and the result of instantiate must be declared:
GameObject foo = (GameObject) Instantiate(sourceObject); // C#
GameObject foo = Instantiate(sourceObject) as GameObject; // C# second version

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:

MS: Using Properties, and C# Properties Tutorial.


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#:

transform.position.x = 3;

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:

Vector3 pos = transform.position;
pos.x = 3;
transform.position = pos;

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:

// a common Unity monobehaviour event handler:
function Start () { ...function body here... }

// a private function:
private function TakeDamage (amount) {
    energy -= amount;
}

// a public function with a return type.
// the paramter type is "Transform", and the return type is "int"
function GetDistanceTo (other : Transform) : int {
    return (transform.position - other.position).magnitude;
}

And the equivalent C# methods examples:

// a common Unity monobehaviour event handler:
void Start() { ...function body here... }

// a private function:
void TakeDamage(int amount) {
    energy -= amount;
}

// a public function with a return type.
// the parameter type is "Transform", and the return type is "int"
public int GetDistanceTo (Transform other) {
    return (transform.position - other.position).magnitude;
}


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).

Houdini answered 6/6, 2023 at 2:38 Comment(5)

and this answer should be a community wiki as well..

Battery

Yeah yeah.. but this questions smells for wiki.. you had that in your mind I would guess before posting it.. :)

Battery

you still get rep points for the question :)

Cholecalciferol

No, as far as I'm aware, because the answer is CW, anyone can edit it, but nobody gets rep. However because the question isn't CW, you'll still get rep for upvotes to the question.

Cholecalciferol

This was amazingly helpful, and in fact, answered some UnityScript syntax questions I had. Thank you! I wish something like this was incorporated in to the documentation.

Knownothing
S
0

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.

transform.position.x = 3;

in C# you should write

transform.position = new Vector3 (3,transform.position.y,transform.position.z);

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

void Start ()
{
t = transform;
}

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.

Strict answered 6/6, 2023 at 2:18 Comment(2)

@Cyclops we should merge all good answers in one community answer..

Battery

@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. :)

Strict
H
0

I'd just like to add to the casting section, in C# there are two types of casts that produce different results when failed.

// These are both C#
GameObject go1 = (GameObject)Instantiate(prefab);
GameObject go2 = Instantiate(prefab) as GameObject;

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.

void OnCollisionEnter(Collision collisionInfo)
{
    GameObject go = collisionInfo.gameObject;
    Actor actor = go.GetComponent<Actor>();
    if(actor = null)
        return;

    if(actor as Monster1 != null)
        // Do Monster1 attack damage

    if(actor as Monster2 != null)
        // Do Monster2 attack damage
}

Using the other casting method would cause all sorts of exceptions, and wouldn't actually make any sense here.

Horvath answered 6/6, 2023 at 2:18 Comment(2)

if(actor as Monster1 != null) If you're trying to do this, a better way is: if (actor is Monster1) Easier to read your intent, and works exactly the same way. Save "as" for when you actually want the value.

Woodsman

very nice and deep answer :) +1

Combs
U
0

Who’s the accepted answer was extremely helpful, thorough, and insiteful, the difference in syntax is irrelevant. If you can code in javascript you can easily learn c#. However c# is 100 times more powerful and I feel like anyone using javascript or boo is being lazy and cheating themselves out of unitys full potential

Usually answered 6/6, 2023 at 2:18 Comment(2)

c# is 0% more powerful and 100% more inefficient, basically you have to write double the amount of code to achieve the same goal.. its a obsolete fetish like linux or macs..

Amado

For scripting maybe. Not for full fledged OOP. Javascript isn't even close

Usually
N
0

For some reason, if you’re reading this article in 2018 or beyond to check if it’s OK to use Unity JavaScript these days, the answer is NO. Don’t use it. Use C#.

Unity team deprecated JavaScript in 2017.

If you’re a web developer who wants to learn C# fast, then check this tutorial for JavaScript developers.

Naturalist answered 2/10, 2018 at 2:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.