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.
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 and suspend it until the script finishes recompiling, so 1 reload for both after-compilation and after-enter play mode.
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.
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.
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...
The most subjective thing is interface design (if you "like" it or not), but 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. 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. It’s funny that Unity’s UI can only get dark after being “professional” lol. But overall, too busy UI for my taste.
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 yet, Unity is making a project like Book of the Dead or The Heretic precisely to dispel this kind of myth.
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.
Sequencer / Timeline
It's a continuation from the last point, 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 a clip and also a track but they are not the real thing but will become real when 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. 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
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 is 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.
Let me tell you my own story.
*inhales* the first time I remembered the UI system was bad, 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. Then SpriteSheet 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. 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. Then Timeline came, I ditched the yield return stupid sequencer I code up painstakingly and opt in to Timeline. But then 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. 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 ManagerW menu to fix them. 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. 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. 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 await ing the AAS. Oh, then the drawer for AssetReference broke that I had to write my own every version. Updating AAS version also corrupts the previous entries I had built too. 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 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 and to avoid the dang notch. It is lucky that this change occurs at the same time that TextMeshPro became built-in, so I migrate them altogether. 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 is not backported from 2019.1 so in the end I can't even use it safely, 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. It is inevitable for the better future, sure.
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”!
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.
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.
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, like you get it tomorrow after you said it today. 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. Really highlight full strength of package-based approach.
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.
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.
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. 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.
You know 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.)
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.
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 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.
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 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.
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.
** This article is still in-progress, as stated at the beginning. Likely will be for years. **