I can’t see myself ever using unity for anything. Either unreal or Godot. There is no good use case for unity anymore
I can’t see myself ever using unity for anything. Either unreal or Godot. There is no good use case for unity anymore
The problem is that it's become a much riskier business decision. What if Unity just disappears, or is bought out by another company, or hikes up fees again?
What if there's unfixed crash bugs in the big black box of that closed-source engine, bugs that may go unresolved for far longer since the mass redundances and could sink an entire project?
I definitely have not felt like the language was a top of mind issue for either engine. Much more important is just the built in features that the engine has for things like movement and what not. I tend to assume that dedicated developers are more skilled than I am. So why do people care so much about cpp? Imo it’s just been a tiny bit of extra boilerplate and a sprinkling of macros.
While I'm very new to UE but experienced with Unity, one of the first things I ran into with Unreal was the complexity of implementing a ComponentVisualiser in UE vs using OnDrawGizmos (or a custom inspector) in Unity.
Drawing a couple of lines in editor mode involved dealing with build scripts to add an editor module to the project. While live coding/hot reload works for minor edits, some code chanfes require closing+reopening the editor. In Unity, it'd have been a few lines of code in an OnDrawGizmos function and no editor reloading or messing with build setup.
C++ build times are often terrible and UE5 does not buck this trend. Editor startup and on-the-fly cooking can also adds to the iteration time. (If you're part of a larger team you'll also spend a lot of time waiting for Perforce and watching it compile shaders and recook. OK, so you can't lay the blame for this bit at C++'s feet, but if you're anything like me then this will give you additional time to spend thinking about how much the iteration time sucks.)
The debugging experience is also subpar, because you pretty much always have to run an optimised build, which makes debugging tedious. Missing variables, wonky single stepping, inlined functions that are impossible to breakpoint, all the usual problems. It's no fun having to work with C++ code using the disassembly.
Having an enormous pile of engine code to carry around also does not help when trying to get the game into a shippable state. Eliminating all the minor hitches and surprising crashes is a huge pain, simply because there's so many places they could be coming from, and even when it's obvious what the problem actually is, actually fixing it is another matter. The build times (which towards the end of the project are as bad as will ever be) really don't help; you'll be working largely with code you've never seen before, and the issue could be anywhere, so header changes aren't uncommon and spending time deep in thought while waiting for builds is not as helpful as it might be if working with your own stuff.
> Are you certain you've tagged everything as UPROPERTY/UCLASS/USTRUCT that needs to be?
Pretty much everything seems to need this?
> Are you definitely always capturing your UObject pointers correctly?
Idk what this means
> Are you definitely never using UObjects outside the game thread?
Just… don’t? The engine is not safe for multi threaded operations on game state. Why would this come up?
> Is your TSharedPtr structure acyclic?
Idk what this means
> Are you certain they're all getting cleaned up?
Like garbage collected? I haven’t run into anything on that…?
> Have you tagged each one with the correct multithreading mode?
Why would you be doing significant multi threading?
Capturing UObject pointers - in a lambda capture list, I mean. These don't participate in the GC mechanism. You have to store a copy of the pointer in a TWeakObjectPtr or TStrongObjectPtr and capture that instead. Again, nothing actually enforces this, so you just have to be very careful to do it.
UObjects outside the game thread - had this on a recent project where there was a background thread retrieving stuff using a REST API. The data was related to some thing or other that was configured in the editor, so one reasonable-sounding thing to do is hand the relevant UObject * to the thread and have it handle everything. But this isn't valid, because the GC relies on UObject pointers only being manipulated by the game thread. But - and the reader may sense a theme developing here - nothing actually checks whether you're doing this.
TSharedPtr - TSharedPtr is reference counted, so you can't have cycles in your pointer graph. This isn't UE specific (std::shared_ptr suffers from exactly the same problem), it's just another thing that can go wrong that nothing checks for. And it's hard to spot, because there's no built-in debugging features for it.
And regarding tagging TSharedPtrs with the correct multithreading mode, UE5 is multithreaded out of the box as it has separate rendering and game threads, and TSharedPtr is an obvious way to share data between them. But if you do that, you need to specify you want the multithreading-friendly TSharedPtr! (This is a particular pitfall for programmers familiar with std::shared_ptr, of which TSharedPtr is supposedly the equivalent, because std::shared_ptr is multithreading-safe by default.) Anyway, we've had this problem on 2 separate projects, and it wasn't easy to track down in either case. And I'm sure I don't need to specify whether anything checks for this situation.
Anyway, niche or not, I've no idea. I'm no UE expert, just somebody that's done a lot of this stupid C++ crap and helped out on several UE4 and UE5 projects that needed some bugs fixing. And it was just a bit noticeable to me how much the same old C++ stuff (that I've been dealing with for years) was still much in evidence.
I think a lot of ppl that come from Unity want to go all in on C++ and run into issue after issue after issue. Then end up hating the living hell out of it.
I agree with the other reasons, but Godot fully supports C# and C++; GDScript is something you can ignore entirely if you feel like it.
Indeed, one good reason to use Godot over Unity is that you can write (and debug) your game using the latest .NET SDK.
I like godot, but c# is second class citizen in that ecosystem, which they are open about (1) and despite improving (2), it still a bit rough.
“Fully supports”? I’d say more like “works mostly”.
/shrug
Gdscript is a weird stupid custom language. I feel like in most cases you shouldn’t write a new programming language for your application unless there’s no viable alternative.
I know, unreal did it with blueprint, but that’s because there are no good open visual scripting languages; and they had a lot of existing infrastructure from their previous (also stupid, for the same reasons) unreal script.
What they’re doing with verse is arguably also stupid, but I’ll give them the benefit of the doubt on the basis of a) having done it before, b) having unusual requirements for their metaverse ambitions.
Anyway. Godot did have any good excuse; gdscript was not something people asked for or wanted; it was a lazy version of python because actually embedding python was too hard. Other options existed. …but, instead the time and effort went to building a new language.
One thing you can look back at in Unitys history that is interesting is their aborted attempt to have js, c# and boo as scripting targets.
…but over time, it became clear that having feature parity in all of them wasn’t plausible.
I guess we’ll see where godot ends up, but my $0.02 is that as the api surface increases, feature parity is difficult to maintain, and gd supoort for other languages will wane with community interest.
The only language they are committed to is gdscript.
[1] - https://docs.godotengine.org/en/stable/tutorials/scripting/c...
[2] - https://github.com/godotengine/godot-proposals/discussions/4...
Also if your application is bottlenecked by allocation and collection throughput, you might see even greater difference in performance.