Skip to content

Instantly share code, notes, and snippets.

@nothke
Last active January 30, 2024 06:33
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nothke/a3ba1d26668e33955b5ed44b59c67c3f to your computer and use it in GitHub Desktop.
Save nothke/a3ba1d26668e33955b5ed44b59c67c3f to your computer and use it in GitHub Desktop.

Preface

I'm comparing Godot mostly to Unity due to my ~10 years of Unity experience. I'm also primarily working in 3D and C# and that is what I want to use Godot for.

Terms:

  • by "export" I mean a variable exposed in the inspector, that's how Godot calls them
  • I use the word "prefab" to mean a scene that is intended to be instantiated multiple times, unlike a "level"
  • Godot's Resources == Unity's ScriptableObjects
  • Godot's collision shapes == Unity's colliders

Pros

  • Open source
  • Lightweight
  • SDFGI
  • Rendering pipeline is much more unified and easily configurable, while being light and powerful
  • Custom shaders much easier to work with than with Unity
  • Resources can be expanded inline in inspector (by default), unlike Unity's ScriptableObjects
  • Resources can exist "embedded" in the scene
    • This is both a pro and con because it's unclear for beginners

Cons

  • Editor scene view does not show what's happening during play mode
    • It has "remote" view but it only shows changes in the hierarchy.
    • Resource changes are never visible even in remote view
    • Changing parameters in editor (such as moving an object) will change parameters live in runtime, but this is a one-way action and will only be effective if the parameter is not touched by a script.
  • 3D (re)import workflow:
    • Requires you to save each mesh of a model file as a separate resource to be able to link to meshes inside model files, so that reimports would update the meshes in game.
    • Mesh colliders don't update when you reimport the model. The mesh collider shape actually has no knowledge of the original mesh, it keeps a copy of the data. This requires the user to go through each scene using the modified mesh and recreate colliders.
  • Can't export (show in inspector) custom classes (unless they're a resource)
  • Can't "apply prefabs" (can't save a parameter back to the scene once it is "editable childrened")
    • This is useful when a prefab depends on the context, example: a flashlight casts a light, but on its own, isolated in scene, it's impossible to see how the light being cast looks like. So when you tweak light values in an external scene where you can see the projected light, you have to manually copy light parameters to the prefab to save it to all flashlight instances.
  • C# is a second class citizen, and a lot things are either not available in C# at all, or terrible for performance (like raycasts)
    • C# doesn't recompile until the game is run again. This makes exports unavailable until playing. (This behavior actually breaks plugin scenes, if you open a scene with uncompiled scripts, references will break)
    • Profiler doesn't show C# scripts
    • Errors cannot highlight which object has thrown the error in scene
  • Slow "play" in editor start-up times, caused by:
    • running a new instance of the game in a separate window, hence reloading all assets
    • C# compiling (which doesn't happen in the background as mentioned earlier)
    • domain reloading (which in Unity can be turned off for near-instant play mode start-up)
  • Profiler is very bare bones
    • doesn't even have a (zoomable) timeline where you can see events within a frame, only the whole frame timings are shown
  • Making a scene from a branch disconnects all exports assigned on the root that are local to that scene
  • Dropping a scene into another scene overrides all exports in the root. You have to manually "revert" overrides for each parameter.
    • Since node links can easily "break", this makes fetching nodes by name encouraged, which to me is an antipattern
  • Inconsistent scene nesting behavior: scene instances do not expose their internals by default which prevents linking their children to external scripts. HOWEVER, they do still exist and can be linked to if "editable children" is turned on, linked and then "editable children" turned off.
  • Unpredictable resource copying
    • Example: if you drop a model file into the scene, it will keep a reference to the model, if you copy it, it will copy all the underlying data without warning, losing a link to the original model file
  • Duplicating multiple objects that reference each other does not relink references to duplicates but they keep links to original objects
  • No simple distance constraint (joint)
  • Joint anchors cannot be changed after they're created
  • Only collision shapes (colliders) that are an immeditae child of a body are added to it (i.e. deeply nested shapes will not be added).
    • However, there is a way to do that with a script
  • A lot of basic functions require verbose code, which is why I'm compiling these utils
  • Cannot export C# collections (like Lists)
  • Cannot put inherited classes into an exported array
@xbelanch
Copy link

xbelanch commented Nov 12, 2023

At the beginning of the development you noticed that activate the "editing children" of a "scene" and transform i.e. the children's rotation it doen't revert to its original values after disabling the editing children option. As you said during the video "that's a bug": godotengine/godot#45915 (really annoying btw)

@xbelanch
Copy link

xbelanch commented Nov 19, 2023

Mesh colliders don't update when you reimport the model. The mesh collider shape actually has no knowledge of the original mesh, it keeps a copy of the data. This requires the user to go through each scene using the modified mesh and recreate colliders.

Just surprised today that this issue has gone working with Blender 4.0 and Godot 4.1.3: the mesh collider changes according with the modified mesh. I uploaded a short video with a basic example: https://www.youtube.com/watch?v=QJX0osqlZcc

@ywmaa
Copy link

ywmaa commented Jan 29, 2024

Can't export (show in inspector) custom classes (unless they're a resource)

I think this now works in 4.2 ?

I usually create a custom class using "class_name"

And I can export them, at least in GD script.
Is it different in C# ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment