The Choice Between Unity C# and JavaScript

July 20th, 2013

This post was written for one simple reason: the question comes up way too often, and I keep saying the same things and listening to the same counter-arguments over and over again. On top of that, the majority of these discussions take place in discussion-unfriendly spaces, such as Twitter, IRC and, of course, the real life. I just want to write all of my reasoning down, so that the next time it happens, instead of engaging in a pointless debate, I will be able to just link this article.

I will begin by talking about my background in programming, which, hopefully, will give you some idea of the reason why I keep saying the things I say. If you (understandably) don’t care about that, you can just skip the next few paragraphs.

I started coding when I was 12. I had no Internet connection, no previous background in any related fields and no particular interest in science (except maybe physics a bit). On the other hand, by then I’d designed my first pen-and-paper and live action games, and just wanted to make video games. As it is often the case, it all began with someone telling me that you have to write code to make video games (which was the case at the time, but isn’t the case any more with things like GameMaker, CraftStudio and PlayMaker for Unity empowering the non-programmers greatly). So I went to the Kiev’s largest book market on a quest for a programming tutorial book. And I bought it. It was a book on Borland Delphi 6 suggested by a salesman as a perfect place to begin programming. I never managed to do much with Delphi: just a couple of Windows applications which helped me solve my middle school math problems.

A couple of years later, during my senior year in middle school, I began coding in Pascal (which is very similar to the Delphi syntax). It was then that I made my first simple video game: it was an interactive fiction thing based on one of my naïve teenager short stories, something that I would definitely suggest making in Twine. Then came the university with its C++ used for Windows applications (Borland C++ IDE was horrible!), later LISP, assembly languages, PHP and HTML. I tried going through C++ tutorial books and developing a game using DirectX. The bad news was that I found it tedious and just kind of drifted away from the idea. Instead, I learned C# and made a couple of Windows applications with it. It was then that Unity came along.

That’s right, when I first discovered Unity, I had about a year of experience working with C#. I honestly tried using it with Unity, but I didn’t succeed, because at the time most of the tutorials and the lion’s share of documentation were in JavaScript. Now, three years down the line, I have switched back to C#, because my projects have caught up with the possibilities that this language presents, and I know Unity pretty well. My conviction is that when you start working with Unity, your best bet is UnityScript (officially called JavaScript now, but it’s not really the JavaScript that you might see on the web), and not only because of the documentation and tutorials.

A beginner in Unity is likely to have a hard time with the vast new framework that Unity presents. And, frankly, no one needs to deal with both this and things like delegates, constructors, lambdas, events and interfaces. Extensive OOP and verboseness of C# combined with the huge new framework to explore is capable of making people quit game development altogether (C++ memory management combined with DirectX almost did it for me at one point). I know that for some of you the concept of a “difficult programming language” is hard to grasp, especially the knights of shaders and C++, but I assure you, some languages are more difficult to use than others.

Not only is C# more verbose, it also has a way of making you think about things that you would never have thought about. Things like this:

transform.position.x = 5; //UnityScript code

transform.position = new Vector3(5, transform.position.y, transform.position.z); //C#—notice the difference?

And this:

yield WaitForSeconds(2); //UnityScript code

yield return new WaitForSeconds(2); //C# code.

By the way, the call above is in a coroutine, which has to be started using StartCoroutine in C#, unlike in UnityScript, which does it automatically

This is a good thing for an experienced Unity programmer working on a medium to large project, but a disaster for a beginner trying to put together their first Pong clone. Beginners don’t need to think about optimizing for this kind of overhead unless there’s actually some kind of hiccup in FPS of the game (spoiler alert: there won’t be, not caused by this, anyhow). This stuff is just too much information to take in when you’re starting to use a new game engine.

I often hear people say that UnityScript is bad because it is not strongly typed. Well, to that I answer that it is if you want it to be. My advice to everyone using UnityScript out there is to include the #pragma strict directive in the beginning of all your scripts, which makes it infinitely more explicit. It’s also a good idea to use #pragma downcast along with it. You need not worry about it though, because #pragma strict is now automatically included in all UnityScript files! Just when you make a variable, always define its type, and you will be just fine. This is not your typical web JavaScript, boys and girls, you can even use the .NET framework with it without any problems.

Another curious thing about the “conventional wisdom” of Unity programming languages is a myth about JavaScript somehow being inherently slower than C#. This is such a common misconception that it almost became religious. The only thing in which it can be slower is the overhead caused by really convenient abstractions I talked about above. If you know how to use it, you will avoid it, and a complete beginner doesn’t have to worry about it, as we have already established. Now, some people suggest that there is some internal compilation magic going on with UnityScript under the hood, that there is some kind of evil virtual machine emulation going on in the CIL. Some even go so far as to say that C# is compiled, while JS is interpreted. With that being the case, you would expect JS to be slower, right? Right? Here is the Unity community at your service, benchmarking the languages: As we can plainly see, the results are the same or the difference is negligible.

And if that doesn’t convince you, here’re a couple of tweets from people who work (or worked) at Unity Technologies:

To sum up, if you are a beginner in Unity, you might want to consider using UnityScript at first if you will not be working on projects that risk getting really big. If you are experienced in Unity and/or your projects are big, you might want to switch to C#, because it offers more possibilities in terms of encapsulation of classes and optimization, making your large projects more manageable. Namely, people tend to leverage the power of events in C# with great success.

Regardless of what language you use, I think that everyone should know how to avoid inefficient code once they are more or less comfortable with the Unity’s framework. Mike Renwick and myself have put together a short list of things you should check if you’re developing for mobile, but most of those things are actually valid for all the platforms. Apart from that, there’s the official Unity’s guide on optimization. Make sure to check it out if you haven’t yet.

With that I say goodbye and hope that you have a nice holy war in the comments.

Coding, Unity3D | Comments | Trackback

  • Sirithang

    I’ll leave a comment since the thing began with an argument between Sergey and myself.

    First I want to recongnize that yeah, I was wrong. Seing that Unityscript exist as “unstrict” I couldn’t see how they could compile everything down to CLI assembly without boxing everything under cumbersome abstraction. This must have been true at one point, since they were forced in the early day of 3.X to force enable the pragma strict, allowing them to compile everything more or less down to the same things. Bad point for me to not have gone farther than “actual” javascript in my train of thoughts. (On a side note, I’ll add that Javascript, and not Unityscript, is still on top of my evil language lice, being nice to animate a button, but too badly designed and inefficient, both in performance and way of writing, for a real app.)

    On the other side I want to counterbalance a bit what Sergey say here : yes Unityscript let you do thing that simplify the writing, but those are minor thing, that you will just have to know once in c# en never bother again.
    The problem with Unityscript is that:

    1 – it exist only in Unity. Yes Unity become bigger and bigger, and its community too. But still you don’t get any insight from outsider that never touch unity (Stackoverflow), you don’t have external libraries foundon the web doing some stuff you want to do. Also there is a bunch of tool for c#, including the IDE support for auto-completion and analysis (giving you your mistake at real time) that work far less with Unityscript thant c#

    2 – You won’t find any small project of more than 2 persons using US as scripting language (Version control support, refactoring etc.. better inC#, cause of the history of the language, + advanced stuff like DLL binding only possible in c#). Or why loose some time learning a language and then learn another when you’ll become more serious, and not right in dive into c# who will not take you really much time to learn (again some “syntax” specific stuff, but appart from that c# is a pretty high level – help the coder kind of language) and save you the time to make the switch (and loose all the bad habit you picked up with US) later? Think ahead!

    So yes US is a “little” easier, but IMO it doesn’t worth learning as you’ll have to switch anyway at some point.

    PS : little note on the position example, for reference the best way to do it in c# will be :

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

    Avoid some garbage collection & more readable 😉