[=;17083]
These debates are bound to happen and they get emotional because the choice of language is often based on “what you are comfortable with”. I can tell a lot of people here are coming from a Unity background and appreciate its accessibility from C# through the documentation etc. My background: 15 years in professional game development as an engine programmer, I’ve used C++, C#, Java, extensively.
First off all, I think there is a misconception and people are latching too much onto C++. Epic has a far more elegant solution to scripting: Blueprints. Anyone who is comparing Unity C# to UE4’s C++ has missed the entire boat. Unity is also written in C++, they just don’t give you the source code. Any criticism leveled at UE4 because of C++ is equally applicable to Unity.
Secondly, who is coming from Unity and is used to C# should be looking at Blueprints not at the C++ engine source. UE4’s C++ source code is not for people who are used to scripting GameObjects and MonoBehaviours in C# in Unity.
And the final much more heated debate are the merits of C# vs C++.
Let’s start with the “language” part of C# vs C++ and ignore the performance aspects of the situation first:
As a language, C# and all languages built around the IL specifications are inferior to C++ because they lack several major features: compile time const-ness, a true Turing complete template meta programming solution, pre-processor macros that support substitution and reduction, the ability to do full static analysis, and multiple inheritance.
For the beginning programmer what does this all really mean? Let’s take a good example with const: multi-threading. In C++, because of const, it is much easier for me to produce a set of classes or an API that effectively communicates threading semantics between two classes that is enforced at compile time. If I have two systems A and B and they need to share an object, (where A can modify and B should only read) then it can simply be done by passing a “const” (cannot modify) version of that object to B. B can no longer ever call a method on the object that will modify its contents. This is enforced at compile time: if you tried to modify it it would fail with an error when compiling. That alone eliminates an entire class of thread synchronization bugs.
There are equally powerful cases for all of the other C++ language features. They range from convenience, to extraordinarily important if you want to be able to do something truly the right way.
C# has some superior language features as well but they don’t tip the scale in its favor:
C# has anonymous functions and closures: This is incredibly powerful. C++ added this in C++ 11 and it is arguable more powerful there but there is an elegance that C# has because it is GC’ed that C++ does not. If I truly had a wish though C# would have first class methods like Lua.
C# has (at least on windows) has windows forms. Not a language feature but it’s nice for tools.
C# has reflection, which is awesome. UE4 also has a reflection system as well, but it’s not a language feature of C++.
**Now let’s discuss performance in C++ vs C#. This is arguable more important than the language features (at least from some perspectives). **
I will begin with some follow up information if anyone really wants to get into this: http://www.codeproject.com/Articles/212856/Head-to-head-benchmark-Csharp-vs-NET
The bottom line on this point is that C# is slower than C++. And if you use mono to compile your C# (like Unity does) then it is significantly slower. Using the microsoft class of IL compilers C# at its peak can almost match the speed of C++, but those are during its best cases. Generally C++ outperforms C# by a significant margin.
The types of optimizations that C++ goes through are more advanced and more significant than what are possible with C#. For example, did you guys know that every time you index an array in C# there is a bounds check in the array? Also C# has its own set of issues and concerns, specifically with mono: Almost all Generic.Collection<> classes in the C# runtime return structs from their IEnumerator interface (as they should). However, mono does not compile this correctly: and it converts structs to object types on the heap causing boxing/unboxing overhead on each iteration. Bottom line: foreach() is slow in Unity so it can’t be used as efficient alternative to avoiding the overhead of indexing in C#.
C# also makes it impossible to modify a value type without indexing because it lacks reference-to-value-types. Example:
void DoSomethingWithArray(MyStruct] arrayofvalues)
for (int i = 0; i < arrayofvalues.Count; ++i) {
if (arrayofvalues*.shouldBeModified) {
arrayofvalues*.modifyValue = calculateNewValue();
}
}
The above requires two indexes into arrayofvalues, requires two out of bounds checks. Can this be optimized out? No it can’t, the compiler has no guarantee that arrrayofvalues won’t be modified on another thread during the if() and the assignment inside the if.
People say C# bad because it is garbage collected, but isn’t UE4 also garbage collected?
This is a blessing and curse for C# and all GCed languages. Generally speaking GC (managed languages) are a net positive for the programmer.
The reasons aren’t always really what people think: yes in C# you don’t have to explicitly free memory, but that not the biggest win. The big win is that when I’m writting 50,000 lines of C# I don’t have to arbitrate what system is responsible for any given allocation. Because I don’t have to do that for literally thousands of places where an allocation occurs you eliminate a massiave swath of common mistakes: freeing a memory multiple times, overwritting free’d memory, overwritten memory you thought was yours but was free’d and then reallocated and given out to someone else. There are lots of expressions of these types of errors that can happen in a large project. They all lead to terrible issues: one of your objects gets overwritten by random garbage, you get a crash when you try to allocate or free memory because someone overwrote memory and stomped on the internal C++ heap house keeping structures. All kinds of nastiness.
GC is probably the best thing C# really has going for it. BUT it’s not all roses either: let’s not gloss over some realities that all managed (Unity) programmers have dealt with as well: Memory leaks. In C# you either get nullrefexceptions or you leak memory. Because its a managed language, a programming mistake can often lead to leaks instead of crashing. Both behaviors are arguably wrong. And C++ doesn’t really have clear win.
However, if you make a mistake the behavior in both cases (managed/unmanaged) it is still incorrect, just differently bad.
Why C#'s garbage collection is bad, and why UE4’s GC is better.
Both C# and UE4’s UObject and blueprints and gamecode generally are all GC’ed as well. So why did Epic do this? Because there is one major pitfall with C#'s GC: performance and predictability. Anyone who has done anything of complexity in Unity knows the bane of the GC hitches. You’re crusing along just fine and then BAM, a 500 ms pause hits you. Or the lovely continous stutter step every 2-3 seconds.
These are garbage collection spikes and there is no way to control when they happen or for how often, in other words there is no predictability.
UE4 is garbage collected but the way their object system is reclaimed and disposed is designed to be predictable and have a flat performance profile. C#'s GC is designed to work for spreadsheet applications and database front ends. It’s a general purpose GC. It’s not designed from the ground up to be a GC for a real-time application where a flat performance profile is the most important requirement.
Adding C# to UE4 is redundant and not a good idea
So for the above reasons C# is not a wise addition to UE4, UE4 already has a scripting system: Blueprints. Use blueprints for everything you want to do with C#. Use C++ to extend and modify UE4 in any way you want to. You can’t extend or modify Unity at all, unless you want to fork over the cost of a source license. And Epic has made it clear from their Twitch broadcasts that they are working towards an integrated system with to provide instant access to checkins on the main source branch as they happen.
Epic actively wants the community to dig into the engine and extend and improve it. That’s why they’ve given us the C++ source code.
Aside from Blueprints, GC, and C++ UE4 is superior to Unity in every other way
Point for point, system by system, Unity is not competitive with UE4 (except it exceeds in documentation). Not even the slated features of Unity 5 matches UE4, it only narrows the gap a little bit.
There are major systems in UE4 that Unity totally lacks, and they are not trivial things, they are systems that it takes expertise in to replicate. They could be done in Unity of course, and the Unity community has provided addons to fill in some of the short comings, but they aren’t done in an integrated system like in UE4. Here’s some of those missing things that UE4 has but are lacking an integrated solution in Unity:
- A real networking solution with client side prediction and authoritative network architecture.
- Built in platform agnostic online subsystems and match making with support for Steam, Game Center etc.
- Behavioral trees and AI systems: Unity has no system for you to create and produce AI or NPC login. You have to start at the lowest level and write your own code to move objects around. Then pathfinding etc.
- Unity’s mechanim system is not as robust or sophisticated as UE4’s.
- Unity has no material node graph. Unity’s renderer (even Unity 5’s) is inferior.
- Unity’s built in GUI is terrible, but there are replacements like NGUI and Diakon Forge. UE4 is about to get Coherent UI and I’m sure the community will fill this void unless Epic gets to it first.
There’s more than this but it’s just an example of the really hard stuff you still have to implement yourself in Unity or buy piecemeal solutions for on the Asset store. And the asset store solutions aren’t always the quality needed to actually ship something.
TL;DR
- If you are upset that UE4 uses C++ you are missing the bigger picture: UE4’s Blueprints are the equivalent to Unity’s C#, but blueprints are superior.
- C# is slower than C++ in almost all cases, and much slower when compiled with mono which Unity uses.
- UE4’s method of garbage collection is better than C#'s generic GC.
- UE4 is superior to Unity. It’s not merely an equal or an alternative.
[/]
Wow, so much opinion being passed off as fact. Always be wary of posts like these.
A hacked on template system, multiple inheritance and the lack of pre-processor as POSITIVES for C++??? Really
Completely disregarding programmer productivity as a plus? Or the safety the CLR grants? To give preventing leaks or multithreaded programming as a positive for C++… is there an emoticon for mind blown on these forums?
Each language has it’s merits, and C# is nowhere nearly as dire as attempts to paint it.