Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Having worked in Unity as a hobbyist for about a decade and considering the switch to Unreal due to obvious issues Unity is currently facing (3 rendering pipelines being the main one), I'd like to hear more input from the programmer experience in both engines.

I think C# in Unity hits a really nice sweet spot: You have a powerful and expressive type system, can use nice high level features like async/await, you get (relatively) quick compile times which help your iteration speed, and decent runtime performance due to IL2CPP.

On the other hand, looking at Unreal, the main options seem to either be C++, in which case you sacrifice a lot of iteration time due to compiles, or Blueprints, which I really have no interest in (I like node editors for shaders, but i'd rather code all game logic). Those are both unappealing to me so I'm a bit stuck.



It’s not as bad as you imagine.

Here are some of my experiences regarding swapping to unreal:

- the c++ gameplay framework is very friendly. It’s GC, with good high level wrappers that provide stuff like options, maps, classes (ie. Reflection).

- The unreal discord c++ channel is full of people who will actually answer your questions, it’s brilliant.

- Every high level blueprint function is a c++ function. I cannot express how powerful it is to be able to step into the source of like “MoveToPoint” or “Whatever” and see exactly how it was implemented in c++.

- You should use blueprints. It’s like python glue for machine learning; write in c++, but when you need to twiddle an animation curve, or lay out a state machine, it’s pretty good. If you’re working with an art team, they can actually make gameplay changes. It’s very productive.

- Plug-ins are a first party construct; you should use plugins to build reusable content. They’re not quite as good as the unity package manager, but it’s rock solid foundational stuff.

- The compile times are not often an issue; I use the incremental unity builds (it’s a source file aggregation thing, why they called it unity I have no idea) and it takes like what 15 seconds to build a plug-in? Launching the editor is slow 30 seconds?) though.

It’s not all good; it has bugs. Sometimes the editor just goes into crazy mode and needs a restart. When you mess up, it crashes with a segfault.

C++ is just less productive; but I’m using the unreal for rider EAP and it’s pretty good.

So… I miss c#; but overall I would rate my experience as pretty good, and since my experience with DOTS in unity has been, shall we say, 100% negative…

Give it a try. :)


Just want to +1 that Rider for Unreal [1] is GREAT. It's also totally useable for non-Unreal C++ projects. Things like code inspection (e.g. goto definition/find usage/etc) and refactoring are actually fast, unlike Visual Studio. I've got a few quibbles about low-level (think asm) debugging, but I've pretty much moved exclusively to Rider at this point.

The Unreal-specific stuff is nice as well: being able to see what blueprints override a uproperty or implement an event is a huge time saver for AAA-scale codebases.

(Not affiliated with Rider, just a big fan)

[1] https://www.jetbrains.com/lp/rider-unreal/


Rider was damn good compared to Visual Studio, been over a year since I used it and was still in beta then as well


Do you think it is possible to use IL2CPP within Rider for Unreal? Then C# could be used in RFU.


No, IL2CPP is proprietary Unity tech.


By unity build I think they mean all cpp files within a module are compiled included into one (so each cpp isn't a separate execution unit, anonymous namespace etc. will bleed over between files unless they are in separate unreal module or plugin).

Similar to SQLite amalgamation.

Turning it off could parralelize the build more, except linkers are often singlethreaded and bottleneck things enough to undo that benefit sometimes.


You really don't want to turn off unity builds in unreal for anything larger than a toy project. The build system is "smart" (albeit itself is slower than say ninja). It breaks the project up into multiple unity "blobs" for you, and they're compiled in parallel. It also integrates with source control to remove files from the "working set" so if you're iterating on a small file it will be removed from the unity blob and compiled on its own for faster iteration.


Running a unity build [1] means the compiler only has to parse and reason about the headers once. So you lose the parallelism of multiple TUs, but you gain on not doing the header crunching over and over again. Whether your codebase will benefit from that is a matter for testing, but many do.

[1]: https://en.wikipedia.org/wiki/Unity_build


also by using unity build you don't need to link object files. I think that is main reason to use unity build, it eliminates need for any build system and compiling source code in a new machine is as simple as compiling a single transition unit.


Unreal is far too big for one unity blob. It still requires a build system for many other reasons.


C# remains a plus for a lot of game code, but not as much as you might imagine. C++ usage in Unreal is really a small restricted subset of C++. For typical gameplay code, you play within their rules for uclasses/ustructs/etc and it feels pretty much like any other managed GC language. Meanwhile, for places where it matters, "raw" C++ is of course always available.

Re: iteration time, Live++ [1] integration has matured a lot in UE5. That means compiling most code changes without having to restart the editor (or even in-editor game session). Again, not much different than Unity here, though both can break and require editor restarts for certain types of changes.

To double-down on OP, by far the biggest advantage Unreal has for professional development (aka anything you want to ship) is full source code. I've worked in both but can't imagine going back to a black-box engine. Unity/Unreal are both MASSIVE codebases ported across every modern platform imaginable and guess what: there a plenty of bugs in both. I can't imagine going back to an engine where I can't A) see what it is doing and B) fix issues without waiting weeks/months for a patch.

[1] https://liveplusplus.tech/


> Re: iteration time, Live++ [1] integration has matured a lot in UE5. That means compiling most code changes without having to restart the editor (or even in-editor game session). Again, not much different than Unity here, though both can break and require editor restarts for certain types of changes.

A week of doing things in unreal engine 5 C++ has resulted in more editor restarts than years of doing things in unity. They are not really comparable. And this is from someone who have written a a few hundred thousand lines of C++ at Google and no professional experience with C#, getting to a productive state in unreal engine C++ as a solo developer is a huge slog compared to unity.

If you do most things in blueprints then unreal might be fine, but for an experienced programmers blueprints feels extremely slow and clunky to work with. I want to write code.


FYI, you will want to launch the editor from inside visual studio. Here is a wiki game documenting the workflow: https://docs.unrealengine.com/4.26/en-US/ProductionPipelines...

Launching the editor from visual studio makes the code and compile workflow quicker. On our project we take map ids from the command line. Thus I can set my visual studio to open a specific map when I hit run. Compined with a powerful cpu and optimized include what you use header usage the iteration time is compatible to a large unity project.

Unreal has a ton of hidden magic most people only learn from other people. Which is fine if you are working at a studio with other more experienced devs. Not great if like me you started as a hobbiest.


As someone who generally hates visual programming and just wants a text editor, I'd say blueprints is actually one of the most enjoyable of these. They really nailed the editor and you can have a lot of fun just playing around.

Also the c++ unreal shouldn't be compared to pure C++. You're working with the unreal framework which adds a lot of quality of life features. I've been working with it for the last month or so and while it's not as easy an experience as c# it's probably the cleanest c++ experience I've had so far.


blueprints are pretty great and lower the barrier of entry for people (especially for like game jam stuff), but I do wish they would have a "here you can just write some Lua" block sometimes... kinda hard to do structured programming the times you kinda want it.

But the discoverability stuff along with loads of nice error checking are very nice.


This is what i was wondering that wasn't explained in the article... does UE offer some guardrails for working with c++ that make the jump from C# an easier decision?


short answer: yes. If you stay within their uclass/uproperty framework, you have garbage collection, guaranteed initialization of class members, type reflection, etc.

Rare issues come up like: ``` int* Element = &Array[0]; Array.Add(0); *Element = 3; // could be access violation or memory-stomp if array was resized ``` Which can be addressed somewhat by code style policies.

Their garbage collector is also slightly weird in that it most things are deleted when there are no more references to it (as expected) but Actors can be deleted explicitly, in which case all references to them are set to null. This makes a lot of sense for a game engine actually, just perhaps unexpected from a language like C#.


Thanks!


so interesting, as a mostly C++ dev, UE's C++ style feels absolutely awful aha. Of course it mostly has to be like this because c++ used to not have reflection at all but I think that nowadays one could use similar principles as the ones I've tried to develop for audio / media objects in https://github.com/celtera/avendish to implement game objects / UObject in a much cleaner way and with better compile times.

Add a couple custom attributes implemented as a clang plug-in like e.g.

    [[ue::name("Player HP")]]
    int hp{};
which can be done in a couple afternoons by an intern and things would look sooo muuuch better.


Having used Unreal for years in the past (UE4 only), I agree with you that C# would definitely win over the C++/Blueprint combo.

Over the years, especially since blueprints compile down to C++, I've learnt to let go and embrace a lot more this visual programming approach. And it does have its benefits. With a strict approach, just as you would in programming paradigm, the readability and 'visual scanning' of opening old code in blueprints really stands out. You instantly feel where everything is, much faster than scrolling up and down code, navigating to/from methods.

I've had experimented with Unity but I found at the time that UE4 was the way for me. At the time I was even working with some guys promoting UnrealJS or something, can't remember the name now, which was bringing JS to Unreal, but it sort of faded as it takes a monumental effort to bring another language to such platform. Ultimately, blueprints are fine, and I'm only using C++ for A* path finding or other heavy algo where math functions are the main focus. You can also make a library of C++ heavy math'ish things and expose them to blueprint. Overall It's pretty ok.

One aspect that is not talked about much is the weight of it all. UE4 was huge. Recompiling the engine was a 3-4 hours business. When I switched to Godot for lighter games, the whole thing was rebuilt in 5-10 mins.


O_o

Blueprints do not compile down to c++, it’s a VM that runs in the engine.

The reason no one talks about compiling the engine is because most folk don’t do that. It’s like recompiling python.

Sure… if you really want to…


There's an opt-in nativization feature for blueprints that did translate them to C++, but it was apparently brittle enough to be removed in 5.0


Python is not that bad to compile. For me, less than 1 minute for a full compile of Python. A full compile of Binutils + GCC + Newlib is much worse, but it's still well under 10 minutes. I'm not even using a particularly fast system.

Unreal is more comparable to projects like LLVM or Chrome.


I'm a hobbyist who tried switching and really didn't like having to use C++ or blueprints.

Epic is working on a new language called verse though, so that might change the situation.


Why does every game engine seem to write their own language? Why not choose an existing one - in this case C# seems like an obvious choice because it's already used in another major game engine and seems to be well liked.


First of all, you need to understand that all current (serious) game engines primarily use C++, in order to provide maximum performance at the low-level. But C++ is incredibly unproductive as a language for actual high-level game development, since C++ takes ages to compile and has more weird and dangerous footguns than any other language. So developers often end up binding a scripting language onto their C++ core, so they can have fast development cycles and move fast. So even C# in Unity is just a scripting language binded onto the core C++ engine. The problem is that C# isn't a language intended for embedding, and you need a lot of effort to bind the two seamlessly.

When Unity started making their engine in the 2000s they had engineering troubles with integrating the Mono C# runtime into their engine, and eventually they needed to obtain a custom license from Morell to fork and modify to their liking (at the time Mono was the only C# runtime that supported other platforms like Mac OS and mobile, and it was dual licensed as LGPL/commercial). There were also myriad problems with this choice, including being stuck with an outdated version of the Mono runtime which they needed to relicense (at a hefty price) to upgrade, myriad issues with the very slow Boehm garbage collector, etc etc. Eventually Microsoft would buy Xamarin (the successor of Morell) and relicense Mono to the MIT license, which was a lifesaver for Unity since they could now update to the latest Mono runtime at no cost. Still they're kinda stuck with their initial decision of using the Mono runtime, and it seems ever unlikely that they're going to migrate to dotnet (which I've never heard any success of embedding with C++). So in conclusion, it took a lot of time for C# in Unity to be useable to the degree we're at now, and it's more of a special edge case of gamedev history than anything else. Most game engines use a much more easily embeddable scripting language such as Lua for good reason (or end up creating their own language!)

About the topic of why does every game engine seem to go the route of creating their own scripting language, I find the explanation of the Godot Engine devs very well written: https://docs.godotengine.org/en/3.0/about/faq.html#gdscript-... (Godot Engine tried integrating many other languages before deciding to write their own scripting language called GodotScript.)


>The problem is that C# isn't a language intended for embedding, and you need a lot of effort to bind the two seamlessly.

I don't think that it's actually very hard to do it, I've done it easily for Java and I think I remember doing it for c# as well: https://docs.microsoft.com/en-us/dotnet/core/tutorials/netco...

It's honestly just a few lines of C code that you point at some c#/java method and run it. The truth is probably that people want to invent their own languages for their own reasons, e.g to have full control. Personally I've never understood that which is why I know so much about language interop now. Embedding is even easier for various scripting languages. I've also done interop for Dart. I don't like Lua but I've also looked at how easy it is for that. Imo there is no justification for game engines not having a C API so that everyone can code in whatever language they prefer.


> https://docs.microsoft.com/en-us/dotnet/core/tutorials/netco...

Well that's something I've never heard of, seems like a pretty recent API. Though it doesn't explain how to call C++ functions from CLR (not the other way), which is the most tedious and error-prone part. It also doesn't explain how to expose foreign C++ objects to CLR either.


Isn't that just p/invoke?


Unity is currently working to make Unity compatible with .NET 6 / CoreCLR, but they don't yet have a release date for that yet. The progress is being tracked in this megathread:

https://forum.unity.com/threads/unity-future-net-development...


That's interesting. I think it will take quite some time though, it's going to be a monumental task.


I agree, it seems like a huge effort. But if they reach their ultimate goal of shipping an unmodified version of .NET, it seems like that work would pay off:

https://forum.unity.com/threads/unity-future-net-development...

It's also encouraging that they expect it to be less than two years out:

https://forum.unity.com/threads/unity-future-net-development...


> The problem is that C# isn't a language intended for embedding

It has always been intended for embedding, since netfx 1.0: https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-.... Microsoft used it for Office, MSSQL, and probably much more. Netcore has been trivially hostable since 3.0: https://docs.microsoft.com/en-us/dotnet/core/tutorials/netco.... Both can be done under 50 lines of code, that couldn't be further from "not intended for embedding."

You'd still need to export your internals to the CLR, but you'd have to do that with any embedded language anyway.


Actually since Burst and DOTS, Unity has been incrementally replacing C++ with C# Burst subset.


Burst is such an interesting project. The fact that, because they know what they are trying to do more than a c++ compiler really can due to the intended use cases, they can be more aggressive with optimizations like SIMD. I remember a talk where they were discussing replacing c++ code with the Burst stuff as you mentioned, and I recall the biggest reason being they could write more succinct code that kept the speed because they weren't having to convince the compiler to do a lot of optimizations they needed to keep it fast.


Agree. I was so happy when I heard they were introducing an intermediate language and so disappointed when I found out it was custom.

I'm back to being quietly hopeful though:

- Epic ships games and has internal game developers. They're probably not going to create something too dynamic or untyped that has issues scaling. - I was worried about coverage but then realised all of BP is generated from code annotations using the unreal header tool, and they've already done it for Python (I think? maybe just editor functions).

If it's just a textual replacement of blueprint that will be enough to make me so much more productive for gameplay programming.

Might be more likely it'll be used for player-generated-content and their metaverse push ala roblox though.


Verse isn't entirely a new language, it's actually them acquiring the team behind SkookumScript, as well as some external hires such as Haskell/Microsoft Research's SPJ.

Excited to give it a try when it releases, will be interesting. The syntax previewed was... different.


Thing is, it's not just having an approacheable/hireable language, its about the availability of tutorials, learning materials, community, and existing code. That takes a lot of time and its Unity's moat that Epic can't really replicate by creating yet another Unrealscript

You absolutely cannot use UE without ending up with C++, blueprint only shines with animation rigging, material, vfx where you need a lot of quick feedback loop by exploring possibilities.


What's the standard compile time for a short iteration in Unity's C#?

I use C++ in UE4 as much as possible and even the iterative compile time with LiveLink breaks my iteration flow. BP is great for iteration but I keep as much in C++ as possible and this has made things much easier to maintain. At the moment I'm trying to prototype in BP then move completed stuff to C++.


If you have burst off Unity iteration time is a few seconds, with burst it’s under 2 minutes (my experience is that it gets longer as the code grows).




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: