My background: game dev since late 1990s, used Unity professionally since 2014, previously made my own game engines/frameworks (C/C++/Java).
NOTE: I started compiling this list when the most recent version of the engine was 4.2. I've marked instances where the things are clearly addressed by newer engine versions.
Without further ado, in no particular order:
-
AnimationFrames:When creating new animations, selecting them and pressingF2to rename:- Doesn't rename the animation but the selected node from scene tree, minor usability issue there
-
Script editor and/or GDScript
- "Find references" not available..? π€
- I'd like structs and interfaces.. These seem to be in cards, hopefully available someday!
- Too long default delays on code completion, error checking IMO
- βοΈ Can be easily changed, though!
- Could show known types when hovering over variables (as a tooltip)
- Would help with inferred types especially!
var something = $SomeNodePath-> tooltip showingNodewhen hovering onsomethingvar max_size := 666->int- βοΈ Mostly solved in Godot 4.4!
Could be improved by showing the types of script properties/member variables and script constantsLocal constants and variables seem to work fine- βοΈ Solved in Godot 4.5! π
- Functions could also show the call hint when hovering over them?
- βοΈ Solved in Godot 4.4!
- Static methods trigger bogus warnings:
- Shadowing member variables
- If script (that doesn't have class name) has a static function that is called without class name, errorneous suggestion of calling with base class -> doesn't work, would need to name the class
- IMO better not to trigger the warning in this case, it's valid code after all
- Chained assignments do not work:
sprite_a.flip_h = sprite_b.flip_h = true-> error - Gaps in static typing (I always use static typing when possible), getting better though! (4.4. brought typed dictionaries! π)
- For example:
var typed_array: Array[RigidBody2D] typed_array.append(123) # Errors at runtime (which is good!), but editor accepts it without warning
- 4.5 brought variadic arguments, which is nice, but the typing is incomplete:
func do_something_on_tilemaps(...layers: Array[TileMapLayer]) -> void: ... # Can't have typed Array here!
- For example:
- 100% user error, but I was briefly confused when creating a new scene while having the script editor open π
- Confused scene tabs with script tabs (which are, of course, in a separate vertical list)!
- Perhaps the editor could switch to recently used scene view (2D or 3D) instead of remaining in the script editor, when a new scene is created? (Or choose the target scene view based on root node type, rather.)
- Speaking of script tabs: this addon makes the script editor more familiar to me with horizontal script tabs
- After all that: I do like the concept of having an integrated script editor! Even with its shortcomings compared to more established IDEs, it is neat to be able to the code within the editor, and the tight coupling with the scene tree (path completions, signals) is genuinely useful. ποΈ
-
Built-in stuff that I had to previously implement on my own, compared to Unity (this list is likely to grow, as I've only just scratched the surface):
PathFollower- A* pathfinding
- Sound randomization (pitch, volume, audio clip) on audio playback (
AudioStreamRandomizer) - 2D lighting, shadow casters
- Tweens. Can be bound to node -> tween will automatically finish if the node is freed.
-
Lean and mean!
- Generally snappier operation in comparison to Unity, especially starting the editor and running + exporting the game. Nice! ποΈ
- But not always, got a suspiciously long reimport times on a font, was working fine first few times, but now takes half a minute for some reason.. (It's a bug, affects project default theme font: bug report)
- Godot remembers the scenes and scripts I had open (another benefit of the integrated script editor!) ποΈ
-
@exportsare based on node paths behind the scenes..? π€- Let's say I have scene
Mainthat has child sceneUIinstantiated inside - I assing a
Main-script@exportto a node that is insideUI-> works fine (withUIEditable children toggled for assignment) - I edit the
UIscene itself and rename or move the node that was assigned -> now the@exportbreaks! - NOTE: This breaks encapsulation and probably isn't a good pattern to use, still I expected Godot to track the node reference similar to Unity
- Let's say I have scene
-
Curveruns from 0 to 1, seemingly cannot edit that range (have to normalize sample value manually)- βοΈ Now possible in Godot 4.4!
-
No sprite mesh aware texture atlasing / sprite packing (i.e. not storing empty regions of the sprite) built-in?
- To clarify: I'm talking about tight atlas packing (using sprite meshes instead of rects) as opposed to rect packing. Like Unity's automatic atlas packer does, if the sprites have tight mesh generated.
- Godot does have support for sprite meshes already, great way to save fill-rate on (mobile devices)
- Would be great to leverage sprite meshes for tight 2D sprite atlas packing.
-
awaitingscene tree timer timeout doesn't seem to survive script reloads? π€- Outputs various errors
-
Inspector doesn't always seem to match what's selected in scene tree
- Trying to edit a node, notice it's already selected, inspector shows something else
- Click again on the node, still doesn't update
- Have to select something else, then the node I wanted to edit originally
-
(Sub)resources show up neatly nested in the Inspector, that's convenient. π
-
Favorite properties in the inspector (4.4 feature) is great, however, editing multiple objects simultaneously seem to ignore the favorites.. Half-way there! π
-
Audio is imported as is, was hoping to have assets as WAV and only compress to OGG/MP3 in editor during import (or during export at least). No biggie though!
-
Git reverts outside Godot doesn't seem to function very reliably:
- In Unity I often experiment on something, say a prefab, then discard changes in Git (quicker and safer than undoing N steps in a row, hoping to get back to the original state! See note about undo below). After returning to Unity, the prefab is reimported (effectively undoing the edits) and all is well.
- Seemingly in Godot the actual asset ("prefab" scene) is reimported, but the old version can linger around in other scenes that have the "prefab" instantiated as a child? Didn't fully delve into this yet.
- Could be that closing all scenes that reference the asset before doing the revert would be enough to support this workflow, but in Unity there's no need for that.. Mildly annoying.
-
In fact any outside changes (such as Git) can cause issues:
- If I pull scene changes from Git, having those scenes open will prompt the reload in Godot, but still the old data seems to remain (in other scenes)? Have to close the project or all the scenes before pulling changes. π
Haven't tested this yet in 4.4 though.I did lose one recent change when pulling changes and allowing Godot to reload changed-on-disk stuff. Have to keep an eye on the Git diffs when staging! π
-
Speaking of undo... I feel I can't fully trust it?
- Sometimes the undo doesn't affect the thing you expect it to: e.g. I was undoing some script changes in the script editor, but instead Godot decided to undo some editor preferences I had set an hour earlier? What the...? π€
- It is possible I had some other panel in focus instead of the script editor, but I don't know...
- It's good that there is the undo history tab available, but surely one can't be expected to be looking at it all the time
- Sometimes the undo doesn't affect the thing you expect it to: e.g. I was undoing some script changes in the script editor, but instead Godot decided to undo some editor preferences I had set an hour earlier? What the...? π€
-
Tilemaps
- Setting up tile occlusion and physics polygons is a bit cumbersome. No copy/paste? When setting up points, undo doesn't seem to affect them (instead undoes something else, tile selection etc.)
- Likewise, with "terrains" (auto-tiling), tried to set up terrain IDs for multiple tiles, was fidgety.
- One tile accepted the values OK, then tried to select multiple, somehow the values didn't stick. Selected one row of tiles (not everything), worked fine. Then again tried to apply to all of them, didn't work..
- Occlusion polygons seem to be resources and should be able to share identical occlusion for similar tiles: in practice a new occlusion poly is created, even though I used regular paste and not "paste as unique". π€
- Big tiles (= larger than one tile) felt a little counter-intuitive to me:
- Say I make a 2x1 sized tile, it renders like that (although offset needs to be set, otherwise it is centered and looks off), but only takes space of one tile cell in the tilemap. I'd prefer it to take 2x1 cells. Makes for easier tile processing in scripts; e.g. "is there a tile here?" -check will now fail on the second cell of the 2x1 tile, because it is "empty".
-
Documentation on the whole is pretty good, I read lots of it when evaluating the engine, even before installing!
-
Pausing game is elegantly handled with the scene tree processing flags (
process_mode) that get inherited- Good for pause menus etc., they're simpler to create than in Unity!
-
In April 2025 did an audio processing/visualization tool (see my blog post ):
- Started with GDScript for rapid prototyping
- Eventually hit a performance problem with audio waveform rendering
- No problem: converted that rendering component to C# and got
20-30x70-80x (in release build) speed up! Just like that! πͺ- That is quite awesome and very powerful: replace individual components with C# (or C++, even) if performance problems emerge. π
- I've still kept the GDScript-version up-to-date, as it's much faster to iterate on it with script hot-reloading.
-
UI
Control.pivot_offset: coming from Unity (and own custom engines), I'm used to pivots being proportional to the object size (percentages), i.e. [0,1] (or [-1,1]) in range. Can't quite grasp why Godot uses pixels aspivot_offset. π€ Feels counter-intuitive to me.. (Same can be said ofControl.positionalways being the top-left corner, not affected by the pivot!)- Fox example, say you have a score label that pulses (with a tween) when score changes. Score label size can change depending on the score text, so you have to manually set
pivot_offsettosize * 0.5after changing text, in order to pulse from the center position. - Sure, you can probably order your node hierarchy in such a way that this is not necessary, but IMHO it would much simpler if
pivot_offsetcould be set to(0.5, 0.5), i.e. always centered no matter thesize.- βοΈ Solved in Godot 4.6! π (
Control.pivot_offset_ratio)
- βοΈ Solved in Godot 4.6! π (
- Fox example, say you have a score label that pulses (with a tween) when score changes. Score label size can change depending on the score text, so you have to manually set
-
...To be continued...
Hiii, part of the Godot documentation team. This is a pretty exemplary list as of writing this. I like these miscellaneous, yet focused descriptions of problems that every user may experience (including me). These may be subtle, but notable.
Unfortunately not every reference to a variable may actually exist at runtime, due to GDScript's design. If refactoring were implemented, finding references would have to be, too. This has been heavily requested and a testing PR exist too.
This has been proposed in #1103 and its reception is lukewarm. I personally see it as more trouble than it's worth for the reasons discussed in the proposal.
See #4081 (#4248), #4457, and #966.
Sounds like this issue. This isn't a problem exclusive to exported nodes. But in a way, yes. If the path to a node were to change, all additional changes done to the same node in all inheriting scenes may be lost. This is a known, pretty nasty pain point. It could be solved with unique identifiers for every node in a scene or an universal refactoring tool. It could be done automatically, but it may be slow.
For WAV files, not quite. It's possible to compress them when importing, just not as OGG/MP3. Since 4.3 it's also possible to import any WAV file in QOA (Quite OK Audio) format.