I have been wanting to be able to objectively compare feature parity between different engines for sometimes. Most devs I encountered are too “cultist”, worshipping only their own is not enough but must try to obliterate the other side.. or just simply throw this line “try it and you’ll know why it is better” rather than addressing a specific advantage.
I have experience in Unity for 6–8 years, while Unreal Engine is just started around January 2019. It will come in handy when I see things in Unreal Engine that is sorely missing in Unity, or just recently added but in preview status, or in a development road, etc.
This article is not for Unreal Engine user, because I did not spend time explaining Unity terms. Unity user will be able to follow because you are just as new to Unreal as me while knowing what’s available in Unity.
This article is in-progress. Because I can’t know Unreal throughly to judge objectively overnight. It will probably takes years to complete and make a completely fair judgement.
This article is biased towards bad stuff in Unity. Because I already know what’s not so good in Unity side but not so much on UE side. Also I notice something that generally UE user are very loyal to the engine and try to convert Unity users, while Unity users actively trash talking their own engine.. I think I am becoming one of them.
How I get used to Unreal will be via smaller side projects. *My UE adventure was halted because my MBP Early 2015 is apparently not enough. I am saving up money and waiting for AMD Zen 2 CPU to come out, then build a new PC with RTX 2050...
I will not provide verdict like who wins and scores on each aspect like those phone review websites either, I don’t want you to be “too long didn’t read” on stuff.
It is to prevent ambiguous claim. If I say "Unreal is much more powerful in 3D rendering" (this is one of the most popular claim) I would have to say exactly what is it that make the difference, that make it more powerful. If it is "just" better but I am not able to know why, I will state that explicitly.
Otherwise this article will become like fanboy VS articles out there. These are some of classic claims I keep seeing over and over, without reasons :
- Unity can't make beautiful game. The rendering is not powerful enough as Unreal. (What technology in the pipeline made that difference? Why is it higher or lower "grade"?)
- Unreal Engine is not suitable for small studio. Unity is better and friendlier for indies. (Why? What is that friendliness?)
- Fuck Epic (Why?)
- Unity-made game is not scalable. You simply can't make AAA games in Unity. (Why? Where's the blocker? It would be better if you says Unity terrain system is not good because xxx, and large scale games uses terrains a lot, therefore Unity is not for large scale games. That would be objective.)
- C++ performance is better than C#. Why? Aren't they just languages? All things became assemblies? Didn't UE also has garbage collector? Magic? Could you tell where is the actual cost of C#, how Unity use it inefficiently, instead of attacking the language?
- Unity is slow, Unreal is fast. Why? If you can point out that UE's blueprint generated code is fast because instantiation of each uses C++ object pool, you are an intelligent UE user. If you can point out that Unity is slow because IL2CPP surprises, you are an intelligent Unity critic. If not, you are not objective enough. We will avoid fanboying behaviour.
Play Mode iteration flow
Right off the bat, I will start with one thing super notorious in Unity, assembly/domain reload time. If anything is a reason to stay away from Unity, this is it.
That is the time it takes to enter play mode. What domain? This is not a compile time that you see the spinner, but it is the time that C# reset its state which is the pause after that spinner. And it is the pause before entering, and also after recompiling script each time. No, asmdef will not help you, that only helps with the spinner and not the freeze afterwards.
At first it is not much, but as you give in to Unity and grow your project.. years passed and now to enter play mode it takes 20 seconds!! And it even doesn't have to take that long, my stupid-looking game is already taking 11 seconds to enter play mode.
It is a lot, it adds up the more you want to do iterative design and it throws you off the flow, most importantly.
And what’s worse, it depends on the project not the scene. If I create an absolutely empty scene in a heavy project, to enter play mode on that scene would take as long as the other scene.
Judging from this thread it seems UE can iterate pretty dang fast. It is one thing that make or break the engine choice to be honest. I can see myself choosing UE just because of this.
The most painful however, it feels like you are “tricked” into Unity by its deceptively friendly entry, but revealed later that the performance degenerates as you goes on at the same time you think you cannot go back now that you got this far. And no one could tell you about this. It may increasingly be the case that everyone has his first project in Unity and learned the lesson, and now sticking with Unreal because there is no hidden problem waiting at the very end. (Is it true?)
If you ask me if I can migrate project instantly without any time cost (but you cannot come back to Unity again ever) would I move this project to Unreal? No, I still value Unity's interface. For others, I can see that this is a sound option given how important it is to quickly iterate on the play mode.
This is worse than bugs which are quite rampant in Unity. Bugs could be reported and fixed. This is by design and unfortunately not a good design.
How to avoid entering play mode
It is ironic that I have to avoid entering play mode when I am using a game engine. This area makes Unity sounds like a still in-development engine rather than a complete one.
What is the solution then? Make a new project, lol. It's not a joke however as recently with Unity Package Manager you could link packages from other places. If you make your game in pieces, and use a new project to edit those pieces, then the project that contains each individual pieces will have an acceptable iteration time. (Pieces inside the same project is useless against domain reload.) And Unity Hub now could quite easily open multiple instances of Unity. Fortunately multiple Unity instances is not costing much. I could have up to about 3 Unity on my MBP Early 2015 open at the same time.
Some other way to fight with this, for example, exploiting
[ExecuteAlways] but it comes with its own challenge to make it works in both prefab stage and normal scene.
Unity's Timeline feature is also a good solution because you could preview time-sentitive things like UI transition without entering play mode. (As opposed to
Animator which its state machine is only available in play mode) Imagine games made before Timeline's addition that is trying to time some explosion effect together with some other event.. how many play mode enter-exits... after 2019.1 you could add signals which emits events. It could trigger in edit mode too but it may link with other play mode only things that you have to enter play mode anyways.
Each play mode is rage inducing because I then found some little bugs that prevents it from going further, I feel stupid and also have to wait more 30 seconds for script compile x1, then it reloads after the script compile and also again when entering play mode. (Fortunately exit play mode won't reload)
If they add some button I could press in play mode so that it restart play mode instead, I could save 1 domain reload on entering. Unfortunately, no option here is comparable to that.
- Recompile and continue playing : 99% of the time everything breaks. You will want to exit and reenter anyways.
- Recompile after finished playing : my default option, but takes 2x domain reload for after recompilation and on entering play mode.
- Stop playing and recompile : only if this option enter the play mode automatically again and suspend it until the script finishes recompiling, so 1 reload for both after-compilation and after-enter play mode, it would have been great. But currently it is not like that and works just like you stop the play mode by hand. So you pay one reload after the compolation, then you pay another on pressing the play mode button by hand.
When it is a phase to iterate by entering play mode, I have to work laying down on bed so I could recover my back spine while it reloads. (It takes that much time that my back actually recovers) Also it helps to close my eye in between each play mode. The time taken to enter could save my eye sight in the long run rather than having to look at freezing Unity editor.
There is an urban myth that “Ori and the blind Forest”, a beautiful game which used Unity, take 1 minute to enter the play mode! Imagine getting a runtime error on the first frame after that wait...
This affects integration test badly
Or called “Play mode test” in Unity. "Play mode"... oh no. Now even if I have a proper TDD design to automate testing of my scenes, I feel reluctant to click on the integration test because it would take so long to start one. The only remedy is to run multiple tests in a row as entering play mode is only once. But that also has its own challenge as the test “spill over” to the next, because the “sandboxing/clean up” you got from enter-exit play mode is now gone. (Also it is usually the case that you run individual test at first and fix problems, you run them all after your game shipped and test for regressions.)
UE also has “Automation System” to run integration tests. Still not using it yet, but it better be faster than Unity. In fact from Unity’s entering play mode performance, I guess it should be faster than Unity.
This is a now famous number from Unity at GDC 2018, where the company start pushing the "Performance by Default" motto. Which gives everyone hope. The clip has been fast forwarded to that time :
What's reassuring is that the CTO himself is feeling the same pain as you! He's saying it. Changing C# script in a large project file, reimporting, or anything, should cost less than 500ms, but it didn't! He said it made him angry. To be honest that sentence made me happy.
But what's worrying is that how could Unity get there? Currently it is like.. 20-50 times of that time. It will be damn great to create in Unity once all the pieces assembled together.
I could see some of the pieces previously, even though it is not explicitly stated in the patch note that these are the part of 500ms plan :
- Incremental compiler integrated to take advantage of
- Unity Package Manager (UPM) system, works well together with
- Shaders compiles and applied to the scene asynchronously. (The blue flash you see briefly when changing materials)
We could see some more of them coming :
- ECS which system class code naturally has no data necessary to reload.
- Subscene which prebuilt memory data
- ECS eliminates the need to remap connections and delegates at runtime.
- Burst which could selective compile a section of code.
- New custom YAML serialization in 2019.3.
- Or manual disable domain reload and type cache API which I am about to explain next.
These are definitely the pieces to that 500ms. You could feel it.
I am thinking of printing this and frame it, because finally we could do something about this dang curse. So the domain reload is not going anywhere, but we could turn it off!!! If you sure you don't have
static variable junk from the last round of play or you design them properly that old value has no effect, then this... is the future.
Unity team said that resetting all the
static is the big part of time taken. So if you ended up hand-resetting all of them later then no gains. But it is better to design without
static in the first place just for this feature. Here's where you could try it if you are on alpha version.
By the way, my game that was 11 seconds to enter playmode is reduced to only ~0.5 seconds! That's surprise me not in just that the number is so low, the number arrives at around 500ms, so it looks like CTO had measured a theoretically possible time before making that announcement?
See this document : Entering PlayMode faster without domain and scene reloads. It's a very big deal that we have to change how we program things to accommodate this.
In that docs it even said the combined domain reload time of all Unity users in the world is about 8~9 years per month, which would be saved by this upgrade. Holy cow.
C# reflection system may looks evil but it is actually the base of many important systems in Unity, particularly the type information which we need to constantly ask the whole assembly what it got right now. Many editor code and of course ECS need to be kickstarted somewhere with a list of all possible types defined. Serialization too, so it knows the structure of that type.
In 2019.2, Unity made a move to address this. This blog post summarize very well what is the problem and it is closely related to play mode iteration time. Check it out :
(You can see it is becoming a theme with Unity and later in this article as well, that you will see they openly say what went wrong, and not afraid to say "so we are scrapping this and that". I love this. No other company's patch note talks like this and just talk about improvements.)
Meanwhile in Unreal...
Blueprint is a visual scripting system in Unreal (before UE4 it was using a system called Kismet). Many compare Blueprint with Prefabs in Unity, but it's more than that. It is a codegen. So the graph you design could be individually compiled into C++ code. And in the context of play mode iteration, this means the compile time will not expands exponentially like Unity because each one compiles individually.
Ok, the compile time is equal to the spinner in Unity but we were talking about that freeze afterwards. I think there is no domain to reload in UE. It is so damn fast to enter play mode. Unity's disable domain reload added in 2019.3 is at best a band aid compared to this.
Meanwhile in Unreal (2)...
With tech from https://molecular-matters.com/ UE had licensed, now C++ could be hot reloaded! Not that entering play mode is fast, now you don't even have to exit. Meanwhile in Unity you must exit, wait for spinner, wait for domain reload freeze (out of edit mode), wait for domain reload freeze again (on enterint play mode).
Unity team said in the forum they could do much more once their ECS revolution is done (2022?) including hot reloading. But in UE you have that now.
All these affect your game shipping date directly, so UE feels like an engine that could get a job done thanks to this alone. Please step up, Unity...
We have arrived as a subjective thing is interface design (if you "like" it or not), but I am going to turn this into an objective discussion as promised at the beginning. In UI world we are able to compare their function and how it affects the workflow. We touch the UI at every moment. And so this is the objective part of UI. What's the resulting speed of work from using the UI? Turning from likings to measurable "time".
There are papers and text books that compare usability of UI regardless of you like it or not. And in some case if both application could perform the same result, all the difference are in UI design.
Unreal looks quite dated in my opinion, where the world had already moved on to “flat design”. It uses gradients, a lot of 3D in the UI that’s not the viewport, and a lot of curves/rounded corners. Thankfully, the UI color is industry-standard dark. But overall, too busy UI for my taste.
It’s funny that Unity’s UI can only get dark after being “professional”, I saw someone refused to use Unity because it couldn't get dark for free, a valid reason. (He opt for Godot instead.) Well I'm fine with grey-white and value my workflow more than colors, but if you are that kind of color-sensitive person then Unity is not suitable for you.
Unity hasn’t update its own UI that flat either (though that’s coming soon in 2019/2020 or so they say with their new UI Elements system?) but default Unity is still flatter, with less 3D icons and less colors.
Unity had major update once where it became compatible with Retina display but that’s about it. The font is also pulled from the OS, if I run Unity on Windows the font would be different.
Well, this is a personal preference but I like Unity’s design better. I like things that looks “techy” and if I may put it in the worst wording “boring”. Like minimal/techno (many normies called bigroom, dubstep, trap, EDM as “techno”, it is wrong) /drone/noise music, not a single of my friend said they like minimal music when I introduce it to them. (some said is this even music??) So “boring” is not a negative to me but more skewed towards “playful”. I feel like I want to play around with it.
Unity’s UI is “tame and clean”. The most important strength is in my opinion fixed line height. (This goes long way into when making a custom inspector) Also Unity’s dark is darker, similar level to Adobe CC’s dark. For example Clip Studio Paint one is not dark enough that it makes the white them actually looks better. But actually I like Unity's free white theme better. (And it is kinda funny that you have to subscribe to use "easy-on-the-eye" dark theme, as stated on the pricing page.)
To draw a comparison to other program, in a DAW (program for making audio for the game, etc) I liked Ableton Live’s design.
Other programs that I don’t like as much looks like this :
Am I nitpicking things? I think not at all. If I am going to use one mechanical pencil every day, I would also complain about the material it was made of instead of functions (so all could write almost equally) as I have to touch it every day. GraphGear1000 is awesome by the way, just the right weight and good finishes on the barrel.
In the DAW business, almost all DAW is capable of doing the same thing. But the difference is the feel they give, how they present the feature and keep the flow. Making music is very spontaneous, speed of getting to your idea became more important than features because you could make music otherwise not possible if the DAW is not inspiring you. For example Ableton Live I am using cannot do “prefab” equivalent kind of thing in music making, but in turn that encourage slice and dicing clips without worry about reuse. It encourages experimentation and mesh well with other “dirty” nature of that program. There are other DAWs suitable for more organized composers. I got the same feel from Unity, while feeling incomplete and wonky it encourage experimentation. (Something that usually waste my time on actually shipping the game to be honest.) But unfortunately, all advantages I like are nullified with Unity's notorious assembly reload time.
Unreal Engine is very resource intensive! I got a warning dialog on opening up about UE is best on quad core something something, but I didn’t think it would be this intensive. On the default scene with 2 chairs, rotating the viewport with a mouse already present some lags. (Around 0.3–0.5s, imagine I rotate quickly and 0.3s after I have already let go of the mouse the screen is still spinning, catching up with the remembered “motion” I did.)
Here’s the spec that is not enough.
I will get a new desktop computer later, then I will be able to evaluate UE more.
I have no problem in Unity so far with this spec. (Also I could open 3 Unity instances at the same time) But however I read from multiple places that even with decent i7 computer the reload and compilation time didn't improve. So it appears that if you have powerful computer you may want to go with Unreal.
Epic is no doubt a very successful company that throws money left and right.
Epic Store is using money to yank games from Steam with exclusivity deal like the case of Shenmue 3. Smaller devs too, however games like Terraria refused to "sell their soul" no matter amont of money.
And yes, Fortnite. Read this interesting article how Unity CEO talks about it. The company's wide reach is impressive. There is even a Reddit sub called Fuck Epic. Everything will eventually be hated by someone out there, but when you got a sub devoted to hating you, you know you are very popular!
And let's not forget the drama between Unity-Improbable-Unreal. As a person that witness the event unfolds, the entire drama still remains an impressive business lesson to me, and show Epic's business character very well.
Initially it's between just Unity and Improbable, then Unreal CEO from nowhere tweeted to his advantage. The tweet wasn't wrong even though Unity's term wasn't clear, because it starts with "did" as a question. Follow up tweets describe Epic's own strength, again not wrong, but it reads like Unity didn't have these features (I guess as an intended effect of the tweeting). As when I thought that's all the win-win Epic could reap in this event, overnight, the 25 million$ funding blog post appears and Improbable is now strongly sided with Epic. It's just... wow. You should Google to read more by yourself, it's already out of topic enough.
Now the game engine. Unreal Engine has about a decade more development time in it compared to Unity. Both engine had transitioned licensing scheme to become more indie-friendly as it is today. UE take game's revenue, but at the same time big games are trusting Unreal.
Unity needs more time to make up for those dev time difference. Not to mention there are a lot more breaking changes recently as opposed to the rock solid foundation of UE. Unity is now building that foundation, a new engine that is no longer have to carry any weight from 15 years ago, with their Data Oriented Tech Stack (DOTS) movement.
If you enjoy underdog story or something in-development you may like Unity. I also liked Unity because it's fun to follow what the company will come up next against the big giant UE, in addition to extensible UI that I like.
See these posts which summarize quite well.
Made in Unreal AAA titles are countless, like Monster Hunter World and Kingdom Hearts 3. Unity seems to be go-to choice for mobile indie devs but those game rarely advertises that it was made by Unity as compared to Unreal. This makes Unreal’s public face very strong, as it is “trusted” by big games. At the same time it unfortunately make Unity feel like a “less professional” choice. (Of course you could make your Unity knowledge a profession!)
In Monster Hunter GDC presentation, there is one point where the dev shows an early build and says this is an "old engine" before they moved to Unreal. From the looks I think it is likely Unity. I wonder what the dev discovered that made the switch. Is it some bugs? Integration with Speedtree or Havok? Or play mode iteration time that builds up? But even looking at the graphic I could get a feeling that it is "kinda Unity", just because Unreal Engine is so often associated with beautiful graphics. ..where actually the dev may not have put in proper lighting or proper terrain yet, Unity did made a project like Book of the Dead or The Heretic precisely to dispel this kind of myth, and I think terrain of those demo doesn't "looks Unity".
If you use
adb logcat while starting a mobile phone game and see a log from Unity then you know that game is one. Almost all mobile music games I know was made by Unity.
Practicality of features
In multiple places, UI, and release note, I can see Unreal Engine is being very practical in each feature. This feature do this and that. Their features are high level and specific. And often looks like a result from their own games. Some feature like big map streaming is obviously from Fortnite, where in Unity the feature like this is called "DOTS ECS Scene Workflow" (which could be memory loaded and stream kinda the same way) but you see it is not as obvious as the "this could make this" style in Unreal.
I will give you one UE patch note to read : https://docs.unrealengine.com/en-US/Support/Builds/ReleaseNotes/4_22/index.html versus Unity's https://blogs.unity3d.com/2019/04/16/introducing-unity-2019-1/. While I know Unity is releasing a very exciting tech like DOTS audio, most of them feels intangible to typical users.
Closed source, and the pain of “extern”
In Unity, when you can’t quite figure out why something went this way, is it your fault or Unity’s fault? You would turn to Unity’s CsReference which is the C# part open for view in the GitHub. But in the end I would always come to the dreaded
extern. That means from this point it is in C++, which is the closed source part that Unity didn’t open.
UE definitely feels more reassuring when you know you can dig as deep as you want and even edit something. Even if I didn't use UE at all, in an hour I could pull the source code from Epic's GitHub to explore and deduce if Unreal allocate memory in data-oriented or object-oriented style. (Read about my deduction here.)
For example of problems about this, I have been researching about audio latency in Unity and it results in this huge article.
But to write this article, it is a result of rage-inducing probing around what I cannot go in and see. (Trying various input into a black box, and reason on the output) A lot of mysteries that I must assume why it turned out that way. It would be much easier and informative if I can go in and see why Unity set sampling rate to 22,000Hz for some of my phone. That's a magic number.
The dang Animation panel that don’t let me play only once for like 7 years ago and it is still that way. I wonder how animators can work on a short UI animation while seeing it loops like crazy. See this thread I got no answer.
And the curve adjustment UX is stupid. You can't edit X Y Z tangents of a scale together. See this thread I got no answer.
If I have an access to the source like Unreal, I would have go in and add some small usability feature by now instead of waiting years because the priority is not high enough for the rest of the world for them to care.
They used a voting system on requesting a new feature, which everyone got 10 points to freely allocate in and out. Imagine I post a request to let the animation play once, now additionally I have to rally a campaign somehow to get points so that it is not only me that is requesting for this feature. (Others might encounter this pain, but did not come to check my request and vote)
But does the "source included" really is what you want?
To contrast with the previous section where I had trouble debugging into Unity's black box, this one I think Unity get it right. Unity have something even better than source included.
Unity started to bring up things you actually want to edit
Basically, very deep features are coming from closed source C++ to C# package which are all readable and editable. It goes very well with Unity's closed source + license fee scheme, the engine code is still closed.
The first revolution is the SRP (Scriptable Rendering Pipeline) where we could edit rendering steps to the point that it breaks all existing materials, then we have DOTS (Data Oritented Tech Stack) where we decided to use hand-allocated space in C# instead to optimize cache usage, then DOTS Audio is coming where we could essentially make a new mixing pipeline on thread if we want to. The incoming New Input System let you access the input buffer memory that hardwares are sending in.
These are things I actually want to edit. In Unreal, because the source is included theoretically I could do the same to surgically change rendering steps or audio mixing. However, the way Unity did is "serving up" to the user without the engine code in the mix. The modular approach.
In a way I feel even better than Unity one day says "the engine is now open source and is hackable to the core", because I don't have to worry breaking the engine, I could edit things I care about with full Unity support. I feel like I could make the engine my own faster than UE, where the theoretical upper limit of what I could change is unlimited, but it is no use if I am not going to that limit.
It draws parallel to Android where it is advertised as fully open OS, most Android believer attack iOS with this argument, yet most user will only "mod" the phone on higher level. We don't actually want to change the OS, how touch detection works, how audio HAL submit audio frame, etc.
The same in Unity, I don't want to change the UI to pink or move the play mode button to bottom bar (where if it is 100% open source like Unreal, I would be able to do). I want to optimize rendering and mix faster audio, and they are providing that without breaking thier own closed source business plan.
I think it take a lot more work to enable this in the most flexible and safe way, than just open up the source code and let user edit it freely like Unreal and claim everything is possible.
Could Unreal do this modularly too? I don't know. But my Google search yields no result about rearranging rendering pipeline. For example, switching the clear color step to the last step for some stupid reason, where in Unity SRP you are able to do easily by coding in C#. Still, Unreal's theoretically could do this by editting the source.
However, I heard big companies would go great length to make the engine "their own". This is the real strength of Unreal's C++ source included feature. And you could fix all bugs by yourself theoretically, because in Unity you are always at risk of waiting for Unity team to look or fix what's in the black box.
Company owning a game vs not
In a nicer wording Unity don’t want to compete with their own user. Instead they made a demo project to test a use case on various things.
In Unreal undenieably when you see Fortnite, you would think you would have the same feature set and resources to make a complete game like Fortnite. If some feature would be sorely missing, then Fortnite can’t do that either. They must have some pressure to keep Fortnite a good game. So they must implement something new.
In Unity, user sometimes feel if the team had any pressure to implement something real quick at all, because they don’t own a game? Like the sunsetted UNET networking system with the new one only on preview. If Unity own a networked game, what will they do in this situation? Or the “new input system” that the team had been working on for 2–3 years. It is just a feeling, but can’t deny the “Wow, I am using the engine that made Fortnite!” feel.
For instance Unity can’t do localization built-in while in Unreal it is there. A game of Fortnite caliber should be able to accommodate multiple languages, and that feature should be there in the engine not from external bought packages. And yes it is really there. SDF text rendering is in UE for very long time too, while in Unity it is just integrated as a package not long ago.
Project-breaking, reworking madness
Continuing from the previous point, In Unity, I would need something like I2Localization asset store package. And localizing is something that should be done while you make the game, if you decided to add it later then have fun updating everything and every text… it should be integrated and thoughtout in the engine to prevent this kind of “mass rework” which cost time.
And also imagine pre-2018.3 era, you cannot even reliably make the button the same instance. The button usually contains a text, and that problem connects with localization.
Start seeing this kind of "reworking" pattern? Imagine multiply that by more than 10. Let me tell you my own story.
*inhales* the first time I remembered the UI system was super bad with that IMGUI-in-your-scene, so I used NGUI asset store. Then uGUI caught up with still-bad tag-based sprite packing system, so I moved to uGUI with external sprite packer, while a part of my game is still NGUI. Then SpriteAtlas (asset) appears that makes the packing transparent and good, so I migrate again and have to relink all the damn picture I used in the project because all the GUID changed. (Thanks to VSCode I was able to surgery the GUID for the entire project but one-by-one per piece of sprite) Then, the font rendering system sucks. This is connecting with localization again of course. Then TextMeshPro came around which uses Valve’s distance field rendering, requiring a replacement of the entire game’s text, prompting an entire replacement of texts in the game. Then Timeline came, I ditched the yield return stupid sequencer I code up painstakingly and opt in to Timeline. But then (unluckily discovered later deep into the commitment) there’s no event in the Timeline! I then hack up a portal to activate the event from clips, then in 2019 where Timeline “Signal” came I would want to opt in to that instead. Also discovered Timeline could only “hold hands” with the Animator and non-legacy animation clips. There are some legacy clips I used for performace which became incompatible with the timeline, previously compatible with the manual code sequencer madness I was doing. To play animation simply I then need to create a TimelineAsset wrapper with one Animation track, or use semi-official solution. Then Unity Package Manager came, I was using Git Subversion to share common code between projects. It was not good because script GUID cannot be shared and it unlinks the entire project with just a small mistake. When I moved to UPM basically all my shared code got unlinked for the last time, and I have to manually rewire everything. (and never again, thanks UPM) UPM also adds its own frustration, every time you do an upgrade you have a chance of strucking in the state where packages error, but because UPM is a package you cannot see and use the “Package Manager" menu to fix them, creating a deadlock of doom. This cause a reimport-all and various combination of pinpoint Reimport for it to work, typically costs around 3 hours. (I remembered because I did it enough time) Then the Resources folder system sucks because it is the only way to load things on demand at runtime, and it is a nightmare to maintain paths that it make sense. But we are all put up with it like it is so natural to load things from folder path, and carefully craft the path so equally ugly hardcoded string make sense. Then Addressable Asset System came, as I read the description I was drooling and wonder why I could put up with the Resources folder? Then I have to migrate Resources to AAS. I thought it would be easy, the API even said you can use Resources path as AAS key and it would still work. But no! Now everything are async-based. And your synchrounous code now have to be infected with callback hell. So it is not just “replace Resource.___ with Addressables.___” as advertised. Unity is not committed to C# async/await yet. Then I looked around for ways to minimize this pain and I found UniRx.Async package that would let me maintain linear code. I then go around and update Resources based code to awaiting the AAS. Oh, then the drawer for AssetReference broke that I had to write my own every version update. Updating AAS version also corrupts the previous entries I had built too, fair enough that it is in preview status so I can't really complain. Then there are some UPM packages that you must use the “staging” version, but some package like AAS if you use the staging version then it break your project and officially discouraged in the forum. Then, using AAS you need a better resource releasing scheme based on reference counting. Also this invalidates the asset bundle system, which is a good riddance (actually it is still hiding inside) but I have to learn how to host things the new way. Then adding UniRx.Async would break the PlayerLoop hackery that ECS package is doing. Causing more problems. ECS itself cause my entire game to be remade, for the better future. Nested prefabs again cause my multi-scene LoadSceneMode.Additive hackery to looks unbearable and I remade them into a single scene composed of prefabs properly. In remaking the UI to nested prefab I have to redo many animations because they are now linked differently. Next up is not Unity’s fault but the world had moved on to super long 2:1 screen and I was doing as long as 16:9 only, I had to remade many UI again to fit. Also in the process of this remade, Unity still doesn't have a proper support for the dang notched phone at edit time. I foresee a remake is coming so I made my own Notch Solution so I could take care of the notch at the same time as this 2:1 rework. It is lucky that this change occurs at the same time that TextMeshPro became built-in, so I migrate them altogether in one go, and together with localization. (I was lucky with my timing, but imagine someone who decided to touch up the game a bit too soon as each feature came in...) ECS came with its own little apocalypse which I am happy to take the pain because I signed myself up for this preview, for the better API, but still it's an another rework. Almost forgot about Assembly Definition File, the idea is great, but a code that went too far is difficult to separate into asmdef without cyclic dependencies, so one another thing that should have been opted-in from the start but at that time it was not available. The asmdef feature also got increasingly better in each version, like now you can put in custom defines and dedicated test assembly. This again cause a problem in asmdef planning for my Asset Store item as I would have to wonder if the asmdef will be backward compatible or not. And crucial feature like ignoring invalid assembly instead of error will not be not backported from 2019.1 so in the end I can't even use it safely without dropping support for the "just 1 version away 2018.4 LTS" which will lasts for 1 whole year with tons of users, lol. In the latest 2019 alpha the asmdef just gain expression-based include, which I think should be there very early to prevent this kind of non-backward compatibility problem if I want to use the feature. In 2019.1, Timeline is becoming a package as a part of UPM movement, breaking many old code and plugins that assumes timeline is built-in and now needs using statement. 2019.3 the UGUI package is now needed to be linked everywhere. I could see an official Localisation package looming next year too, so a yet another round of "rework all texts in all scenes and prefabs" game by then. In 2019.3 the enter play mode is now lightning fast, except to use that it breaks the world again because domain no longer reloads, requiring all plugin owners that assumes the domain would be reloaded to take action.
Thankfully that I am not making a networked game. I have heard some more rants from people that makes networked game and “mistakenly” used Unity’s built-in networking solution and are regretting. Imagine how scary it is to wake up and see a big UNet text gradiented by nice “sunset”!
In an ideal world it should be impossible for the user to make a mistake of committing into something heading towards its demise but unfortunately we all make mistakes. Think about this, what if I used the pen tool in Illustrator and one day they announce that the internal data structure of vector path is changed forever , and all paths made with "the old pen tool" will not be compatible with the new one and a conversion is not possible, you must remake it. That would be breaking the world. (But Unity do try to push a new motto "performance by default" where you can't just make a bad choice, let's see it happen.)
Or just read the comment of this blog post about the solution of what to do in this transition. Or this new update post in April 2019. You can see the users are outraged and already fed up of this endless reworks.
Or the Collaborate function. The little dropdown around the menu bar. I think it had been advertised since around Unity 5 where there is a built-in source control that was said that it is better than Git or something else because you could merge scenes, assets, and you could do it all from inside Unity, concurrently while multiple team members are making games at the same time.
Sounds tempting, and I almost give in but I am still sticking with Git in the end as I worked alone and visible
.meta file plays nice with Git. I also remembered trying it as far as Unity let me do it for free, but I remembered the interface is very clunkly, sometimes doesn't update or requiring restart, where my Terminal + Git would already get the job done. Also I have worked with a game company which uses this feature and they said it brought more trouble.
And fast-forwarded to now, collaborate is now being rebuilt! I am grateful that Unity often comes out and says what went wrong, UNet and now Collaborate. But it must be frustrating for those who tried to live with the feature. New Collaborate is enabled by the recent UPM package movement which is currently breaking everything.
Enlighten the lightmap baker is now being replaced too! What could go wrong from here? Read that blog's comments too while you are at it. And reasons in the forum, before you start hating Unity for deprecating stuff. In there, you can learn a lot about pains from real users. Unfortunately I am mostly with 2D games, so I can't say more. (I used baked lightmap only once to make a music video for hobby, but not in production.)
One relevant article about software rewrite here is an another good read : https://medium.com/@herbcaudill/lessons-from-6-software-rewrite-stories-635e4c8f7c22. I did chuckled a bit at the Basecamp part.
The comments are mostly in the same tone as this article : "I love Unity, but man, how painful it is when foundations after foundations collapsing randomly over time". I am not surprised at all why AAA devs do not want to risk their game with Unity's surprises like this.
Unity make this kind of move very often and is not afraid to try. The engine is going on a big transition and just starting to be usable, it is even more painful to not migrate to these new things when you know it’s there but you are still doing the stupider way. UE's release note feel more like a new extension rather than reworks of features.
The problem is that how could someone new choose the right one? There are too many traps in Unity. To name them currently :
TextMeshProUI. You are doomed if you used the normal version.
- Tag-based Asset Bundle vs Addressable Asset System. AAS ended up using Asset Bundle underneath but it save you from manual bundling madness and extremely unintuitive tagging way to determine which goes into which. Also using the bundle is the actual nightmare to code. When it works I am not even sure what I did.
- Default project vs LWRP/HDRP. If you switch to LWRP later on then all your textures may become incompatible. Also shader graph is only usable on LWRP which will make you switch later.
- If you don't make your game in packages early on, you are stuck with compilation and domain reload time of doom. It is because you could go to an another project to work on a part of your game that gives UPM-based development an edge. But think about it, it is funny that I have to split my game into pieces just because the script piles up and add domain reload time on unrelated or even empty scene, that a workaround is go to a new project without scripts and use UPM to link back. UPM do make me a better coder however. The scripts are ready to be reused in projects in the future.
I wished these things are there from the start. Right now Unity looked much more reasonable, even though most packages are still in preview status I consider them essential.
My hunch is telling that Unity is far from done doing this big migration.
- UI Elements break your editor code next?
- UI Element runtime deprecates uGUI?
- New input system breaks uGUI event system?
- What will become a package next?
- DOTS-everything breaks everything?
- Nothing is compatible with Tiny Mode?
If you want to stick with Unity, you have to move forward with them constantly. (Or stick with LTS version, but new features are usually deal breaker since Unity was too incomplete to commit a version freeze throughout the project's life. I like that my project is becoming better overtime and my design has moved from monolithic to a more ready for change (agile) design. But as a result I have lose so much time too. All my subversions gone, my personal toolbox all became UPM.
But Unreal is definitely more suitable for professional in this regard because it is relatively more stable, professionals may not want to always catch up and maintain the project to latest tech but rather just have to ship in time. You can freeze the engine and evolve it yourself by editing the source code if you really want a complete control, which is a corporate-thing to do.
Unity is now getting modern that they adopted NPM-like approach, called Unity Package Manager (UPM). (They like to attach U to everything, now there's also UXML and UCSS)
Asides from transition pain I talked about in the earlier section, in the end this will be a good initiative to foster code reuse and code sharing community. No more having to post your source code in the forum to copy, for example.
I used to read Unity's version release note with excitement whether it will contain THAT bug I reported long ago or not.
Now, as more Unity internal component get migrated to packages (which will break the world and cause necessary pain) we could get updates from each of Unity's internal team delivered, with its own
CHANGELOG.md to read, out of release cycle, in parallel! I really like this. Also it plays nice with Assembly Definition File where it split your game into several dll.
Also it is possible to make your own
package.json and include it from local disk, or even pull from GitHub. I could imagine a vibrant community made scripts being shared on GitHub which I could include in a project in seconds, and transparently because they will not occupy
Assets section of your project. This make your
Assets section truly your game.
This is a example "shape" of compatible repository, containing
package.json at the root.
I find this very refreshing, much like what Microsoft transitioned into. Meanwhile in Unreal Engine, this is their package system :
So it works like
.unitypackage that Unity had. External things (like from the store) are imported, not linked. Source control contention they mentioned in that page is solved with UPM in Unity.
Packages and the forum
I had never been to Unreal forum, but Unity forum which was mainly for users, right now after this UPM movement, each package mostly gain its own forum and we could talk, suggest, and report to the devs directly.
This is huge, I could get personal with a particular feature's developer! Gone is the feeling that big company that made big program is out of reach and nothing we complain could reach them. (For example, I am sure don't want to suggest anything to Facebook or Adobe because I think it is a waste of time.)
I am impressed by the Addressables sub-forum in particular.
unity_bill who is a developer for this feature is very active and address (no pun intended..) ALL threads regularly. One thread I posted long ago I already forgot, he bumped the thread and say this problem is fixed in the next version. I mean, look at this. It's phenomenal!
Or recently, the Quicksearch package which provides "Go To Anything" popular functionality often seen in IDE.
This thread is particularly spectacular, the turn around time of reporting bug is fantastic. As soon as he said a new fix is available it really is available on my Package Manager UI, press update, and it fixes the problem instantly! It's.. magical. Look at this, it's about an hour ago and it is already there.
It really highlight full strength of package-based approach. And currently I think even if I don't count just game engine competitors like Unreal Engine, but expands to other softwares, Unity is still among the earliest to adopt this modern design.
The Entity Component System sub-forum is also very active, and it is exciting that the CTO Joachim Ante himself is around to guide the early adopters since he is also one of the developer of this package. For ECS feature in particular, if someone says that ECS way is slower than mono then he has to debunk it immediately. Since if that ended up to be true, it would defeat almost the whole point of ECS. It's great to see he is not letting any thread that question performance passed by. Also threads about usability get answered, and the dev team could feel by themselves if these thread is difficult to answer, then the API needed more work to be friendlier.
TextMeshPro forum, which Unity brought the developer of this previously-plugin to be an in-house dev quite some time ago, has a very dedicated staff that you could feel he is giving his all to provide us the solution.
It makes me think I am not just a dev of my own game, but for Unity as well. And I am incentivized to do so because it would eventually come back to my game. The bug report feature was already in place for long for that actually, but these forums are the next level. Because not just a bug could be reported here, we could discuss, we could ask how to do things that often leads to a new feature. At the same time it adds Google search hit. Bugs aren't encompassing everything in software development.
And packagize my own game is a lot of fun, it enforces reusable design naturally because you cannot connect circular dependency for Assembly Definition files. (So always put
asmdef in the package, don't be lazy.) It must be one way from the package to my game. You have automatically save time for your future games and projects, or even save time in the same project should some bugs occurs and you could go to the package and fix the problem, not fix the problem in the context of your whole gigantic game.
"Unity's default sucks"
Even with undeniable advantages explained, I still seeing some UE users keep saying something like why Unity has nothing by default (even more "nothing" after this package movement), why must I suffer a hassle of installing a package? Therefore, UE is better. For some reason UE users keep attacking every Unity's feature on every opportunity presents by stating the obvious opposite. Packages sucks because now I have to install packages manually and not knowing what exists. You might as well say buying food sucks because now I have to lose money, where previously I didn't.
Think this way, it's actually good that the engine is not bloated by default (and it will pave way to something like Tiny Mode). Base installation is just 4~5GB with only Standalone build selected. I could imagine a feature like Cinemachine if on UE side, it would be strange for that to not be a built-in. (because realistic stuff, etc.) The wrong reasoning of UE people who are not used to packages is that, he feels like packages are "add-on" and unofficial. Therefore, a game engine that requires an add-on to perform decently sucks and is unprofessional. Actually it's not embarassing at all to build your software from pieces. The world run on open sources, and they are mostly considered packages of sorts.
Right now (2019) you will notice that there is not much in Unity Package Manager, until you press Show Preview Packages. When you do this, you entered not production ready area and it even labels the top of your title bar with a big [PREVIEW PACKAGES IN USE]
The thing is all the goodies are in here. ECS, new input system, addressables asset. Few got out of preview like Lightweight Rendering Pipeline. But even so, many rages when they hit a blocker that prevent them from publishing everywhere they go because they used a preview packages.
Even occured to myself. I think I could get away with it if I use it for "just a bit". No, you will probably not get away with preview packages. Someone successfully used ECS in production doesn't mean you could. I used AAS "for a bit" by having just scenes in the bundle group and nothing else. I found a bug, that took me 3 days and I didn't think the culprit was AAS.
Why people wants to risk their project with preview packages? It's simple and goes with what I said before : It's because rework is immenent. They see if they use this package early they don't have to rework the game later. (Because packages are like Unity, like AAS or ECS, they completely changes how you design things and loves to break everything) But trust me, resist the temptation and just follow the development from a far is usually better for most devs.
Some safe to use preview packages are one that affect only editor like Quicksearch or Immediate Window.
Also, production-ready packages like the built in Timeline doesn't mean you will not find any blockers, lol. In 2019.1, Timeline is a package and wasn't marked with Preview status. But over the course of 3 months I found too many bugs that are critical like Control Track that doesn't work properly, sometimes Animation Track do not sample its last frames when the play head goes too fast or lagging, Audio Track do not play their first few samples, etc. AHHH!!
Prefabs vs Blueprints, a performance comparison
Blueprint is viewed as kinda prefab in Unity, UX-wise. But as I said before that's a common misconception for the actual thing they do underneath. Blueprints are more than Prefabs because it is a C++ codegen system. Where prefabs in Unity is only a data container of sorts, containing how to assemble assets together by their GUID in their
.meta files at runtime. (Same as "scene", actually 2018.3 prefabs are all on the scene backend.)
Composing your game from pieces
Recently Unity shipped improved prefab workflow as of 2018.3 where you could nest, make variants, and edit in isolated environment. It is awesome. After using it I think I cannot go back to the old, “no more than 1 layer !!”, stupid prefab anymore. Megacity demo is impossible without this new prefabs, and here I am not surprised why previously there are so few large scale games made by Unity.
That's the actual hell for UI design where you must choose either make the button a prefab and nothing else, or make the panel a prefab but bake the buttons and make them cursed of not being to receive any more updates ever again.
You see how that sounds very stupid, and that’s true when I said Unity just been able to do this stuff to my brother that has no idea about Unity but is an architect, and he replied “lol that sounds like a feature that should be there in the first place”. (He used several CAD programs which could do layered object instancing, like it should be able to.)
But in UE, the “prefab isolated view” new in Unity 2018.3, is already there. I guess from very early version?
In UE you do C++ first to make a functional Blueprints, then you can connect up visual scripting and spawn Blueprints to make a game. In Unity as of 2018.3 you would make each prefab the similar way and compose up a prefab in the scene and connect using exposed variable slots.
Graphs in the Blueprint became your code, plus your thing. In prefabs you script a code and attach to your thing. There is no visual scripting in Unity, it is in the research section of the roadmap though (Jan 14, 2019). Unity did promoted Bolt asset in the store as a goodies for purchasing Unity, so maybe the official one is still very far off. And again, Bolt is no comparison for Blueprints as Bolt is a visual scripting to program logic, but Blueprints generates code.
Why codegen is a big deal? Because you can't go wrong! The generated code must produce an efficient C++. There are many places that could go wrong when Unity user writes
MonoBehaviour to paste onto their prefab.
You can compile each individual Blueprint
Just from seeing the compile button, I feel like this is one step ahead of Unity in both modularity, AND assembly management. If the “enter play mode” of UE is lightning fast thanks to this design, I wouldn’t be surprised.
It takes isolation to the next level. Event system for example, in Unity you could use
UnityEvent, or the new
SignalReceiver. But the interface presented that you can select the method to invoke is a result of compiling the entire C# project.
But in Unreal, it can immediately show that a function does or does not exist. You can go script it and make it exist and then hit compile just that thing. I can imagine a lot of optimization that is possible in the engine with this design. In Unity, various things are gated by the big assembly it requires. (The UPM deadlock nightmare for example!)
Code-gen visual scripting is coming for ECS
Unity is doing similar approach to Blueprints that an ECS visual scripting graph would produce C# system code. ("System" is the thing that work on entities in the new DOTS paradigm) You could read more in this post.
How does it compare to Blueprint? Both generates code, but ECS System code do not carry data but work on data coming from anywhere, inside its
World the system was placed in. UE's Blueprint code includes data fields because it is an object-oriented design. Let me remind you again that ECS code gen will not directly solve assembly reload time of doom.
However that's not an upgrade to the prefab, the current topic we are talking about. (But since Blueprints was compared to Prefabs and Blueprints has visual scripting so I had to...)
Prefab as memory-ready prebuilt data
This is an exciting upgrade coming for prefabs itself. It actually goes one step ahead of UE's Blueprint codegen, because these Prefabs they skip the code and go straight to become memory data!! So the idea is, nothing could be faster than just putting a pre-made memory into the game hardware memory at runtime, where this data was made at game's building.
(For UE Blueprint codegen or regular Unity Prefab, the code would usually then allocate data and setup your things as designed in editor, at runtime. It is costly to resolve all the links to your assets.)
It's all beautiful linear memory access blasting through the data
What sorcery is this? So there is always a catch. Those prefabs must be ECS compatible. (Has "data" representation, not just any prefabs.) The stunt is possible because ECS is data oriented and now your "thing" is just a block of data, whenever that appears, the System is ready to work on them. You could just casually stream them to appear over time, as long as it appears in a unit of
Entity it's all good.
Currently, Unity use something called "Subscene" which all prefabs inside it could become memory, and this memory would ship with the game. Though it is strange wording-wise that "Subscene" has more high-tech feature than the actual Scene feature.
Performance of codegen Blueprints asides, now onto subjectivity of visual scripting UX. Do you like creating game by connecting graphs? Or are you a coder?
I know someone who is trying to program UMG (Unreal version of uGUI) and ended up with a huge zoomed-out graph and he think that visual scripting is not a natural design interface. If it was just a code it would be much more easy to understand. (Visual is not always the best presentation)
The advantage of visual scripting is that it gives you directions. It can go “this way” or “that way”. Plus you can see connections.
But sometimes all the logic needs to communicate with you is not directions but reasoning. Top-to-bottom text based presentation (that is coding) may be better in many cases, but you cannot see connections. The connection the coding way got is “line” which flows from top to bottom. If you are a code-person it even feels “visual” when looking at lines, it does not have to be literally visual.
Unfortunately most who claims "not a code-person so I need visual scripting" are just fearing lines of codes without trying. They just want a rectangle to surround something.
But why for shader design visual graph is considered the “standard” presentation? I think it is because you often dissect and mix/merge things, that it benefit from the connections. It is not always the case in coding, where if it ended up “waterfall-y” then visual scripting is having disadvantage against pure coding. Coding is exactly waterfalling from top to bottom plus jumps from method calls. Visual graph is not always an appropriate representation of what you want to make.
Unity's uGUI WYSIWYG
RectTransform designing is one of the thing I really like. I couldn't think of more appropriate way I would like to design my UI. (However its layout performance sucks and every little things trigger layout compute... I hope Unity make the ECS UI or whatever Facebook Yoga layout implementation blazing fast.)
It’s right there! As I double click the shader a very promising UI pops up.
In Unity I can’t imagine the frustration of material artist would have to face before even getting to this point.
- Somehow you have to know that they are not built-in, but available as an official add-on package. UPM is a good initiative, but maybe too geeky for artists.
- You have to on board on LWRP first. After this your game might turns pink and take some time to fix up.
- You have to then get the Shader Graph package.
- You have to migrate your existing material to LWRP then it shows up as a graph. At this point your draw call might be unordered or go wrong, requiring some fix up.
But one bad point of UE is that that UI is extremely laggy. Zooming in and out is steppy and takes a lot of time to pan around. I guess my computer is not good enough for Unreal. I like the explorable sidebars on UE’s UI.
In Unity however it is not very explorable, opening up Shader Graph and see almost nothing is not very comfortable. On the other hand, I like the cleanness overall of Unity’s UI. UE ones is definitely more flashy looking with environment reflection preview and all. Here’s a basic example of a material with a few nodes. *viewport contains some post-processing effects.
Sequencer / Timeline
Unreal got many practical sounding tracks like dialogue, subtitle, layered animation, and even could record animation takes like a real movie editing program.
In Unity we get barebone tracks like activation track where it just set active on the present of clip. It seems to invite you to create a custom track, however amount of learning required is crazy. Even the component that plays the timeline is called
PlayableDirector. I witnessed firsthand on showing this feature to someone and he exclaimed "playable what??".
Then when I explain you have to make playable asset which is not a playable yet, but a magic container containing more containers that are clips and also a tracks, they are not the real thing but will become real when the outer layer timeline which is also a playable asset ask them to and connect to graph ports, then also bindings and output shenanigans it is getting confusing which is which form of which. And which level you can safely extend.
For example I tried making my custom playable asset type, which could be materialized into a file successfully, but I was not able to edit it in the Timeline tab. And also many audio-related things are hard coded, so you could subclass them but have to hack your way to the underlying data so that the hardcoded Timeline source will read it. You can't make it from scratch while conforming to some interfaces and expect it to work.
The API has high potential, but the whole castle is difficult to understand. In fact I think digging the source is faster than trying to read the docs but unfortunately only
Timeline part is available to real but not
Playables. I will not forever know what the heck is inside
AudioMixerPlayable that does the magic with connected
In Unity's fasion, when Timeline first arrived in 2017 everyone was excited and now Unity could potentially do cutscenes or make non-game movies. However for games, it lacks event which didn't arrive until 2019.1. For cinematics, it lacks proper child track and additive track. The "Control Track" is nice and looks like the key to end it all, but on closer inspection it is a band-aid at best since what it does is to ask the other
PlayableDirector to play or destroy a completely different
Playable together while playing the current timeline. It's not a real "inheritance". The grouping feature is there, but to just help you fold and organize your BIIIIIG (vertically) timeline.
And also, see this thread where Unity's mass-demolition of features affects every ETA in existence include the Timeline team. Luckily when packaged it should go more smoothly from now on. (Now = 2019.1 ~ .2)
I am sorry UE fans... but I think Unity had delivered some serious usability threading upgrade with the HPC# subset design. It changed the perspective that now “now everyone can thread!” just like AirAsia said “now everyone can fly!”.
I have read how to do threading with UE and it looked like a typical threading nightmare you would expected.
But C# job system, it might irk you that you have to use struct or you must copy things, but it strike the balance between performance and non-frustration coding experience quite well. No race condition. No memory aliasing. Automatic dependency warning.
In Unity, you don't even have to spin up a new thread and manage it. It uses Unity's "worker thread" that it already is using for engine stuff. When they are not busy, they could do your custom work. This is great not only for reducing headache, it manages work stealing/scheduling automatically for you. (Flashback to that algorithm class!) C# could spin up a thread, but C# Job System that use the already existing worker thread is just better imo.
And if you use ECS, you will thread more naturally with automatic lockstep that avoid write dependencies magically. The downsides is that all these tech are still in preview. New comers probably have no hope on avoiding all the gotchas.
Unreal CEO himself have some say about this too. UE's user code is strictly locked on a single thread, but that doesn't mean it's bad because it constraints complexity and also those code was from Blueprint meaning that the performance is in control and hard for user to go wrong. (Engine code could still use threads) He says more that concurrent language like Erlang is not suitable for game since game needs atomic sync point often.
C# vs C++
C++ has been synonymous with “performance” and most assume that Unreal must be faster. But previously, Unity was slow because it often travels back and forth between C++ and C#. (Mainly the call to
Update) Now with the UPM movement, it stays in the C# realm for longer.
Also with ECS, you could make the majority stays in C# WHILE getting a good assembly with Burst that could beat C++’s assembly. You see, everything became an assembly so it does not matter if it is C# or C++. And Burst is trying to make C#’s assembly competitive. (Read more here if you want to see that assembly, see if you could handcraft C++ in Unreal to beat it?)
Unreal CEO said he liked simplicity of C#, but don't like that the data has to be linked to the actual C++ implementation. That's actually the trap Unity already falls into because
MonoBehaviour also got C++ database underneath. Unity CTO also acknowledged that the foundation of
MonoBehaviour was bad. And Unity is now eliminating that with ECS where the database is entirely on C#, for all objects (
If you love C++ then you probably love Unreal Engine. (?) But I don’t… my experience with C++ the entire life was not good. Naming convention irks me. And I made too many mistakes.
I don’t have any good memories with C++ throughout my master degree study (where I use it for OpenGL and Caffe stuff for neural nets.) so obviously I will be biased towards C# ! So from here I would like to mostly advertise C#.
However Unreal C++ is not as brutal as your previous experience, there are macros to help you. And most importantly Blueprints to help you get the best code.
If you are open minded and don’t mind any of the languages, then you will need to see what civilization in the latest C# that Unity just supported.
The most powerful and game-changing in my opinion is
async code linear.
Even if I like C++, I can imagine programming much faster with
async/await . Also I like how tuple syntax works. Firebase Unity comes with
async/await compatible API and that’s a huge boost in productivity. I don’t know what Firebase API looks like in Unreal/C++.
One of the most popular claim about C++ is that you can use pointers rather than reference type variable. You don't want that pesky Garbage Collector. Yes, you can go
unsafe if you want to do pointers in C#, if that is the reason for C++ for you. The
* deref syntax is the same.
void* is there for you. They even give you an
IntPtr as an almost-
The majority of Unity ECS code (C#) is in
unsafe scope and used pointers a lot. With Unity
asmdef , the
unsafe can be contained in a small scope. (C#
unsafe requires an assembly-level toggle, previously a problem since it makes your entire project unsafe. Not anymore with
Also it is possible to do
unsafe on C# Jobs system mentioned earlier to do threaded pointer gymnastics. When checking the generated Burst assembly I could say it is no different from handcrafted C++ code, so the point about "C++ for performance" is not true.
Lastly Unity made some methods like
UnsafeUtility to help you do malloc from safe context.
If garbage collector is the reason of C++ for you, the latest 2019.1 Unity gives you more control of GC, you can temporarily stop it. And it became incremental, whic free garbage in smaller amount but more often than before, reducing spikes.
More, if you use ECS then your data is arranged in a way that GC cannot touch in the first place. Also, Unreal has garbage collector too.
Other reason for C++ might be the C# language restrictions, like multiple inheritance. And maybe C#’s verbosity. And maybe you hate C#
interface that it couldn't do what you want. (default implementation, inherited generic constraint, etc.) That’s a fair point if you would like to use C++ over C# because of those. But I had already jumped on the Data Oriented Design train so OOP concept like inheritance is not of my interest any more.
For other C++ advantages, if you are C++ expert then you may know more but I am not one. So I could not recommend you any more reasons for C++.
You also have NPM-like repository for C#. Unity supports .NET Standard, if you found something .NET Standard it would be usable in Unity. For example you may use popular library like Newtonsoft.JSON or LitJson without a problem. Anyways, UPM sets to be an equivalent of Nuget with things that works 100% with Unity.
If you are a documentation freak and like to tidy up your code the way you like to make your room orderly, I think C# is good for you. The XML code documentation is verbose, but the resulting integration with intellisense, etc. is great. I enjoyed seeing the code say something back to me as I type.
You can make link to jump to other code, you can use markdown that shows up properly in some IDE, and editor like VSCode can ease the verbosity pain for example typing just
/// will expand to a big XML template depending on the thing under your cursor. Then mass-refactoring works throughout the documentation too if you get them linked right.
I don’t know if in C++ it is as civilized or not. But it is a blast creating UPM package fully documented for myself in the future to read on Intellisense.
Let’s talk about DOTS, Burst, ECS, and UTiny/Tiny Mode
Unity is clearly trying to step ahead of Epic Games on this one. I can’t find something similar in UE that boldly tries to change up how you code the game!
For those new to these things, Burst create good assembly from C# custom-fitted to each mobile device. ECS is a new API that allocates a special super fast database for general purpose, but you have to access the data from what the API allows. Tiny Mode has a precondition that you must code entirely in ECS, and it let you strip even more size from the game. These are hardcore and exciting.
Can’t deny that when UTiny’s UI get out to the normal Unity and when ECS is built-in, it would be a ton of fun and geeky goodness for me to play around even more. (Even more that I might keep on improving the innards of my game and never release it lol) As I said more business oriented people are not excited by this kind of thing as me. They want to finish stuff, thing that already worked must not be touched.
That's not all with tiny mode, it is becoming a standalone library that is runnable without Unity GUI looking from the source code. I could see this becoming a high performance toolbox for C# programmers that wants to write data application, like a server code.
Something experimental and engine-breaking is uncommon on Unreal side. But Unity has no fear of doing so. I have talked with someone switched to UE from Unity, he said it is stupid to always make the customer a lab rat for all the features. I kind of agree, but I don’t mind being a lab rat personally. I won not once but twice in a beta test giveaway program where you are given Unity swags based on randomizing through unique bugs submitted. I tried so many shiny features and submit a lot of bug reports. (But he finishes a game.)
Do you often select the hardest difficulty in a game, or remove armors just for self-imposed challenge without any kind of archievement or trophies to back up the reason? I think Unity feels that way. And it satisfied certain kind of devs.
Data-oriented design vs Object-oriented design
As you may know now Unity is building a new Data Oriented Tech Stack (DOTS) foundation, while UE is staying strong in OOP. (Read my deduction that UE has OOP-style allocation)
In short, the strength of DOD is that "The hardware will thank you" because you are playing to the hardware's strength by knowing exactly where the data is and how it flows, while OOP you are playing to your own brain's strength because it is easier to visualize and program, and abstract away those details.
OOP's strength we all love : it's easy to understand
This is highlighted by Epic's CEO which he commented DOD has potential but how hard it is to map game design problems to?
Unity is exploring an interesting direction with their ECS (Entity-Component System), which aims to escape the overhead of C# by moving data away from high-level objects linked by pointers to much tighter data layout, as is commonly seen in graphics programming and particle systems, and is less explored in gameplay programming. What's unknown is the productivity cost of recasting gameplay programming problems within the more constrained data model, and whether it would scale to e.g. a triple-A multiplayer game developed by a large team.
It's true. This area is unexplored and how could we map (recast) common gameplay problem to ECS's strength? It's not like we always make a game full of identical cubes or particles. ECS is good at iteration through linear memory and take advantage of cache line, but how can we design a game to fit this? Unity is working on higher level component that automatically use ECS so "recasting" is not your job. But not now.
Also, OOP doesn't instantly equal slow the same way C++ doesn't instantly equal fast. Overusing OOP's hierarchical design leads to poor performance because you are not aware of it's data structure. Read more here : OOP is dead, long live OOP.
DOD's exciting untapped potential
I will simply quote from http://dataorienteddesign.com, an online free DOD book also available on paperback :
As we now live in a world where multi-core machines include the ones in our pockets, learning how to develop software in a less serial manner is important. Moving away from objects messaging and getting responses immediately is part of the benefits available to the data-oriented programmer. Programming, with a firm reliance on awareness of the data flow, sets you up to take the next step to GPGPU and other compute approaches. This leads to handling the workloads that bring game titles to life. The need for data-oriented design will only grow. It will grow because abstractions and serial thinking will be the bottleneck of your competitors, and those that embrace the data-oriented approach will thrive.
It is simply exciting that you could be ahead of competitors where they couldn't follow you! (If they stayed with OOP) Also that currently DOD is far from norm of the industry, it is also thrilling that you could be one of the earliest adopter, should DOD rise to mainstream fame in the future.
Also there are problem domain that are naturally suited to DOD as well, not just "everything could be thought in OOP". You are expanding your thinking toolbox by knowing DOD, just like reading an algorithm book make you able to map various problems to classic problems solved with graphs, dynamic programming, or clever data structures.
Keep on learning
Putting performance or usability asides. Do you love learning? I really do, but not everyone.
Frankly I have come a long way with OOP and it is getting stale and boring. Reading website like http://dataorienteddesign.com is just like making a new character in MMORPGs as a different class from your old character, it level up crazy fast and fun. Unity may bring pain along the way, DOD maybe super unwieldly to use now, but if tagging along will get me a nice ride on learning track then I'm on it. I know by myself I would get lazy, so it's nice that the engine is forcing me to learn. In this viewpoint I want to stick with Unity because it challenges and keeps me on the edge.
Everything are queued to be reworked for DOTS!!
You read that I have been reworking my game countless times in order to catch up with Unity. Ironically Unity need to rework itself to catch up with its new Data Oriented Tech Stack self, in order to utilize the unlocked performance. Of course our game and editor toolings are queued for a rework next once those came out. What a time to be making games.
Now to the frustrating part. The recent years you could feel it that many upcoming features are delayed or appears stagnant. It's almost as if everyone in the compary was summoned to a secret meeting at one point and told : "You all stop what you are working right now, listen to this... *presents how data-oriented design would save the world* OK, do you want what you are working on to be obsolete in 2022? Then rework what you are doing for DOTS no matter how far away the schedule have to be posponed. Also no one should disclose this to any user since it would be an uproar. It will pays off later guys. We are doing this gently and gradually but if possible we just wanna pull the rug lol.. just kidding. (Or maybe not...)".
Frustrating part #2, it means whatever problems you encountered in the current system (that 95% of users depends their life on), they might not be as incentivized to fix anymore that they have a new and shiny DOTS-based-something cooking internally.
For example, multiple bugs related to IMGUI that I reported was marked as Won't Fix, because UIElements rework of the entire interface in 2019.3 would fix it. Ok, understandable, except that the current TECH stable is 2019.1 and it's frustrating you have to live together with the bugs for potentially 1 more year. It's like you got a toad in the room somewhere and you have to be constantly aware of it.
You feel like the Animation tab's UX was stuck in prehistoric era, because of course, they have the new DOTS-animation system in the work that fix everything since it is a complete rework. They even state that it wouldn't be compatible with whatever exists now!
The new input system project started many many years ago, you could imagine it got some pivot over the year that by now it is not done yet. Maybe they are trying to make it DOTS-compatible but this one no official statement yet. The current alpha (2019) as per source code it use low level native memory access via pointer for interop speed with OS-detected input, but with DOTS they could have that threaded and bursted. I have been waiting in this page for soooo long for the version number to be 0.3, so I could try the new touch input.
Unity SourceTree UI reference seems to be stuck at the end of 2018 for half a year, around the same time they start promoting DOTS that may make it obsolete. (EDIT: It lives again on June!!) They have stated that the new runtime-UIElements would, yeah, again, not be compatible with uGUI.
And of course UNET sunsetting that I said before. The reason a new solution didn't appear promptly is likely because it have to be depending on DOTS. Networking seems like a thing that could benefit from DOTS greatly, if I know DOTS is coming I would also stop my networking team from making mono-based solution for the better future of the company.
DOTS itself get its own rework from time to time, like that big API apocalypse that deprecates
[Inject] junks, or a system version number needed to be passed to the job, or the magic entity command buffer
CreateEntity which talks to the next one spiritually but now fixed to return
Entity properly, or all your existing jobs now has to explicitly register itself to its barrier/ECBS to dequeue commands. All requiring manual fixes.
Something like this I genuinely think is good for Unity. However prepare for shitstorm and countless "ETA??" threads in the forum because people are mad when their stuff break, madder when given a experimental preview but they use it for real and break their game beyond repair, and maddest when they don't know when they could use it. I salute Unity for making changes this big and dealing with bad users.
I have not made any game that uses the terrain system so I cannot say anything. However there are some that says there's a deal breaker in Unity's built-in terrain system where Unreal could do anything, so I think I should include a bit of this. For example this. Use your own judgement. If you have bad experience with Unity terrain before, note that Unity updated the terrain tool recently.
As far as I looked to UE roughly, UE has an explicit support for making a streaming open world thanks to owning the game Fortnite. I think this connects tightly with practicality of UE's terrain feature, since terrain is a big mesh and streaming that means the mesh has load only partially, or something? (I actually has no idea)
Please read the comments below
This article is still in-progress, as stated at the beginning. Likely will be for years. Here, I will summarize what it feels like in a given year.
- 2018 : DOTS announced and at full speed. Deprecations looming. 2018.3 is an important breakpoint to use the new prefabs and package-based development.
- 2019 : DOTS transformation still in progress but still zero usable high-level DOTS stuff. Premitive DOTS that is ECS still in-dev. Some DOTS backend creeped in silently like audio in 2019.1. 2019.3 is an important breakpoint that the editor changed completely. Massive packagization of Unity, Timeline, uGUI becoming a package.
In the mean time many from both Unity and UE had come to fill in some voids where I couldn't make my judgement because I am not that far into UE yet, in the comments below. Like, I didn't think UE would be that difficult to program a custom shader without hacking engine code. Also it is nice to see almost every one stating opinion objectively, from personal experience, complete with "why".