41 minute read

Moving from Godot to Unreal

This post’s main goal is to cover migrating from the Godot engine to the Unreal engine. It is not an exhaustive list of every facet of the engine. Obviously I can’t cover absolutely everything, but I try to hit the parts that I see most people (even those unrelated to Godot) struggle to understand. Do keep in mind that not everything has a perfect 1:1 mapping. You should not go into Unreal expecting Godot (and inversely, go into Godot expecting Unreal). They do have a lot of similarities but at the same time, have different approaches to a problem. I also include resources for further reading from other blog posts.

I will not be covering things like the new Mass framework or the Gameplay Ability System either. As a very very quick overview, Mass is Unreal’s new ECS framework that is still under heavy development. Similar to Unity’s DOTS. GAS is an entire framework that supports building out “abilities” and effects. Suitable for things like an RPG or a MOBA. That isn’t to say it is only used there. Fortnite uses it quite heavily. Both of these are more advanced topics and I encourage you to research them when you get more experienced with Unreal. For Mass, this community project is a good starter. For GAS, this community project is where most people start.

I also realize that you have full source code access to both engines and this technically means that you can do whatever you are capable of, but I am only referencing them as is. It is simply unrealistic to try to consider all of the possibilities with full source code access.

Scenes & Actors

Godot presents you with the notion of Scenes and Nodes. You form a collection of Nodes in a parent-child relationship and save them to a file called a “Scene”. All a Scene is in Godot is just a collection of Nodes. Of course, you can have a Scene where there is only one node and that is still a qualifier for being a Scene. You typically end up building each Scene as sort of a game entity of itself. Something like a character or a chair or a weapon. Scenes can even contain other Scenes! In fact, oftentimes, this is how you end up building your game. You create small Scenes that are instanced into other Scenes to form a larger Scene. Then, most often from what I’ve seen, you have your overall “Level” Scene. This is where the gameplay actually happens.

In Unreal, this roughly translates quite seamlessly. In Unreal, you have Actors and these are just a collection of Components. A Component is more or less equivalent to a Node in Godot. They have data & behavior encapsulated in them. They are expected to perform some kind of behavior. As an example, to display a 3D mesh in Godot you would use a MeshInstance (MeshInstance3D in Godot 4.0) Node. In Unreal, you’d use a StaticMeshComponent. You then take these Actors that you have created and put them in a Level. In Unreal, these are your .umap files. Inside of these .umap files is where the gameplay actually happens. Now, you typically don’t compose Actors of other Actors the same way that you would do it in Godot (Scenes being inside of Scenes that is), but the option is still there with the ChildActorComponent. This component allows you to have a fairly similar workflow to Godot when it comes to building your game entities. Do note though, there have been reports of it just being buggy overall and it is generally recommended to not use them. Instead, on spawn, create the Actor that you want and attach it to your current Actor through the Actor/Component attachment methods. I’ll leave it up to you to determine which route you want to go.

One difference here is that the Actor is an actual class, where as a Scene is not. So if you wanted to add additional functionality to an Actor itself, you just create a new class and inherit from Actor, then add that functionality. You cannot do this in Godot. Everything is handled through Nodes and the SceneTree class. You could create a new class and inherit from SceneTree to create additional functionality for the entire SceneTree, but that is an all or nothin’ approach. In Unreal, this is the workflow that you will be doing. You create a new class, say Weapon and it would inherit from Actor perhaps. Then you add the components that you want and write the functionality in the class itself. This isn’t to say you couldn’t just write the functionality in a custom component and attach it to the weapon. How you architect it is entirely up to you.

Nodes & Components

These two pieces are practically identical, so there isn’t much to cover about them. They both get attached to Scenes/Actors. Both have a parent-child relationship depending on how you arrange the Scene/Actor. Both have a version that doesn’t have positional data (Node for Godot & ActorComponent for Unreal). Overall, really, these are the same thing. One might argue that Nodes aren’t like Components because you can add a Node to your level scene, but you can’t add a component to your .umap map. This isn’t a difference between Nodes and Components, but a difference in how the engine encourages architecting your game. In Godot, your level scene can be seen as a game entity. So, in that sense, your level scene is just an Actor that has a component for everything in the game world. If Unreal wanted to organize it to be that way, they absolutely could’ve done that and allowed you to freely add components to maps. They just opted to not do it that way.

Gameplay Scripting

This is probably the section most people are concerned about. After all, if you can’t add functionality to your game, the engine is practically a non-starter for you. Godot uses a custom scripting language, GDScript. It also supports using C# and whatever language that is bound to the API through GDNative (GDExtension in Godot 4.0). In Godot, you create a script and then attach it to a node. This script extends the functionality of that node. The script is inheriting from whatever class you extend from. The script essentially becomes the node. This is nothing special really, it is just basic inheritance in the Object Oriented world. So, to create your gameplay behaviors, you write a script, attach it to a node and then execute on that behavior. As an example, let’s say you had an AnimationPlayer node and wish that it had some function that allowed you to get the current animation’s exact play time. Well, just create a script, add that function, and now you can freely call it on any node that has that script. You are extending nodes to add custom behavior. You are extending the engine without even realizing it. You don’t have to go into C++ and modify the engine to add this additional behavior.

Unreal is largely the same way. It uses a visual scripting language called Blueprint to handle it’s gameplay scripting. It also supports C++ as well. In Unreal, you will create a new class that inherits from something, say, Actor or ActorComponent and then add your gameplay functionality on top of that. Just like GDScript, not everything is exposed to Blueprint and this is where C++ comes in. Admittingly, it is far easier to get C++ working in Unreal than it is in Godot, partly because this is the expected workflow. And yes, this is even taking the new GDExtension into consideration. In Unreal, you just click on “Add New C++ Class” from the tools menu in the editor and then you start writing C++. Of course you need the tools installed as well (MSVC stuff, I’d recommend reading the docs on this, it is extremely straightforward). There is no repo you have to clone. No additional build steps. No config modifications. Nope - just have the tools installed and then add a new class.

The way it interopts with Blueprint is a more seamless experience as well. In Godot, in order to expose a method to the scripting layer, you need to have a _bind_methods() function and then in there, do the following for each function - ClassDB::bind_method(D_METHOD("{method_name}", "arg1", "arg2"), &ClassName::FunctionName);. This is a lot of boilerplate. In Unreal, you just add a macro right before the method (typically done above the method), UFUNCTION(BlueprintCallable). Done. Now of course, this is because of Unreal’s custom reflection system. Unreal has a tool called Unreal Header Tool that goes through and looks for these macros and then inserts the relevent binding code inside the GENERATED_BODY macro that will typically be at the top of your class. This is why, when you look at the macro definition, they are empty.

As long as you are staying within the bounds of the Gameplay Framework (which you most likely will be when starting out), with C++, it is a fairly similar writing experience to C#. Epic has modeled their type system after C# and has done a lot of work to make writing actual gameplay code as painless as possible in C++. Unfortunately, it still is C++ at the end of the day, so there will be some learning that needs to be done. But a lot of the scary stuff people often complain about with C++ is abstracted away from you. Unreal does have a much bigger API to learn than Godot as well, which often leads to being worried about doing something “wrong”. Don’t fret - we’ve all been there. Just like with Godot, with time, you’ll learn the most common stuff and be writing C++ quite rapidly.

When you are writing C++ in Unreal, you are on the same level as the engine code. You can freely browse the source code and all, just like in Godot. Much like with Godot, it helps if you have some understanding of how to build a game with the engine. But in Unreal, they actually use comments to help explain stuff, even if the code is readable as is. Much like any other large software, the comments aren’t always accurate or even useful, but when they are, it is greatly appreciated. Take a look at the NetDriver.h header file and read the comment there that explains how Unreal handles a lot of important networking info. There simply isn’t a comment in the entire codebase of Godot that is as helpful. Now of course, we can’t forget about the comment in the GenericOctree.h header, for the TOctree2 class. I’ll save you the lookup, “An octree”. So - it isn’t always super great, but when it is…oh man is it appreciated. There are plenty of developers out there who don’t care about comments, but for people who are just getting their toes wet, they can be incredibly helpful.

In Unreal, most everything is built as a module. This even includes your game. This is why you are on equal footing with the engine. Because there isn’t anything special per se about your code, it’s just another module to Unreal. Imagine, if in Godot, you’d create a module in the source code and then write all of your gameplay focused stuff there. Then you’d compile the engine and boot up the editor and start working again. This is the workflow in Unreal. Again, with Unreal though, this is the expected workflow, so the experience is a bit better in that regard. By that I mean, going from C++ back to the editor.

In Godot, you are used to fast start up times and quick iteration. If you are used to using Blueprint, you can get pretty fast at writing code (Blueprint code is code, don’t let anyone tell you anything different!), but it still doesn’t match the speed at which you can write gameplay code in something like GDScript. Godot also has a form of hot reloading with GDScript. So, you can change something in your script while your game is running and then see that get reflected in the running game. Unreal does as well…kind of. It can be a bit risky though. You have to enable it for Blueprint code in your settings and in C++ land, you have Hot Reload (NEVER USE THIS - www.hotreloadsucks.com) or Live++, which is better, but can still cause issues depending on what you do. Get in the habit of shutting down your editor and recompiling your C++ changes for maximum safety. In Unreal 5+, Live++ is enabled by default thankfully, but it is generally accepted that you want to turn off reinstancing when trying to use it. You can do so in your project settings. Live++ is generally seen as only safe if you’re trying to change function bodies, but nothing structural (like changing the .h file or stuff in the constructor).

One other area that generally sucks in Unreal is that in order to get a good C++ writing experience, you need a paid product. That is either the Rider IDE or Visual Studio with the Resharper license. Both of these are from Jetbrains and which one you want depends entirely on your preference for Visual Studio or Rider. The reason you need these is because Visual Studio’s default intellisense can’t understand a lot of Unreal’s macros and code in general. So you get a lot of false errors. You should ignore the error list and only pay attention to the output when building your code as well. Now, of course you can write code without these helper tools, but that is entirely up to you.

One thing I do want to point out is that Godot relies a lot on Signals. This is their implementation of the Observer pattern. In Blueprint this is called Event Dispatchers. You’ll also hear them being referred to as delegates.

Here is a post from Tom Looman that gives a very good guide on C++ inside of Unreal Engine. Tom’s blog has a lot of good posts that you should reference when you get a chance.

And another one from Laura’s Blog.

Data Handling

In Godot, the primary way to handle custom data for your game is through custom resources. You can create little data objects and then create instances of them in your filesystem. Your scripts can then reference these instances to help facilitate a more data-driven approach.

In Unreal, the closest equivalent to a custom resource is the Data Asset. One difference between the two, however, is that Data Assets are not expected to have any actual functionality. They are meant to just hold data. This isn’t to say that you can’t have behavior in them. After all, they are UObjects at the end of the day (UObject is equivalent to the Object in Godot).

Unreal also has Data Tables which can be used for the management of data. These are pretty much dictionaries (called TMap in Unreal) where FName is the key (FName is similar to StringName in Godot) and the struct is the value. So you could create the same thing in Godot with custom resources, but you’d also need to build up the tooling around it as well.

Garbage Collection

Unreal does utilize a garbage collector, meaning that there is something that runs periodically in the background to free up unused resources. Epic has tuned this for game development specifically and I haven’t hit any hitches due to garbage collection. You have to register something to the garbage collector in order to make sure it stays alive. This is often done by just using the UPROPERTY macro on a reference variable to any UObject object. You can also modify how frequently the garbage collector runs in your project (maybe editor?) settings. By default it runs once a minute. However, I don’t think I’ve ever seen or heard someone actually altering this value.

In comparison, Godot doesn’t have anything running in the background to free up the unused resources. Instead, it opts for the more simplistic form of garbage collection that is reference counting. Most of the things that you interact with in Godot don’t actually support reference counting. Most notably, Nodes. You need to be a descendent of Reference (RefCounted in Godot 4) in order to take part in this side of Godot. So resources (and that includes your custom resources) are reference counted.

Do note - this doesn’t automatically mean that Godot’s system is better or more lightweight, just because it is more simple. There is a common pitfall with relying on reference counting as your primary means of garbage collection. That is reference loops. Pretty much, there is a chance that references don’t properly decrement and can cause a memory leak. This happens when you have two reference counted things holding a reference to each other and then both objects are destroyed.

Animations

In Godot, you can use the AnimationPlayer node and the AnimationTree to handle virtually all of your animations. You can animate practically everything in the details panel of a node, which is really neat. In Unreal, it isn’t as straightforward when it comes to non-skeletal animations. There are multiple systems at play here, each serving a different purpose. You have the Sequencer, which is more for animations inside a map, Actor Sequencer (experimental plugin that is closer to how you’d do something with the AnimationPlayer), Animation Blueprint (more for skeletal animation stuff), and Control Rig (more for authoring animations and modifying animations at runtime).

The Sequencer will primarily be used to animate things like cinematics or level specific animations, such as a crane moving to pick something up and place it somewhere. You can feed dynamic transform data into some sequences if needed, and this lets you reuse an animation a bit better, but it still isn’t ideal.

The Actor Sequencer is a plugin that you can enable in the plugins menu and is marked for experimental (don’t let that discourage you from checking it out! I explain plugins later). This adds a component that you can add to a Blueprint actor and then do localized animations, kind of like how you can use the AnimationPlayer in a specific scene and everything is local to the scene. This is probably the closest similarity to the node in Unreal.

Animation Blueprint is closer to the AnimationTree than anything else. In there, you have your animation state machine, as well as your logic to process the Blueprint. To better use the Blueprint, it is helpful to know the character animation system overall - and it is extremely powerful. The character animation side of Unreal’s tooling blows every other engine out of the water in capabilities. And it clearly shows. You can use various IK methods, alter bones directly, blend fluidly, modify animations at runtime, and all that fun stuff.

Control Rig is how you can rig a skeleton in Unreal (the actual skeleton should already be imported into Unreal, from something like Blender or Maya) to be able to author entire animations in Unreal or modify the animations at runtime. You can even build a full IK rig and create animations out of no concrete animation asset! Control Rig’s realtime IK capabilites are something that are often glossed over, partly because of Epic’s marketing. I would highly encourage you to really take a look at what it can do. This video is a pretty good primer. I would encourage you to watch the entire video, but I did include the timestamp to start at.

The way the animation system for characters work is that animations are tied to a Skeleton asset. This asset gets created when you import a rig into Unreal. So any mesh that shares that rig, can use the animations. Godot has traditionally struggled in this regard, but is moving to provide better support for it with the introduction of Animation Libraries in Godot 4.

Custom Tools & Plugins

It is a more pleasant experience writing tools in Godot than it is in Unreal. That is until you have to go to C++ in Godot versus doing it in Unreal. Here is where Unreal’s reliance on C++ being a first-class citizen shines again. Just like Godot, all of the UI of the editor is built using Unreal’s UI framework Slate. So if you see the editor’s UI doing something that you want to do, you can do it as well. In Unreal, you often enable/disable plugins through the plugins menu. This modifies your .uproject file (which is an equivalent file to Godot’s project.godot file). The reason writing tooling is a more pleasant experience in Godot though is because writing GDScript is just more pleasant than writing C++. Writing Slate is also a bit different than the way you’re probably used to writing UI code. It writes more like React or Flutter if you’re familiar with those. That said, you can write tooling in Blueprint and UMG (I touch on what UMG is in the UI section). UMG is a wrapper around Slate to make it easier to build out UI for gameplay purposes. So you aren’t forced to use C++, but it just depends on what is exposed. You can also write custom tool scripts in Python if you so desire. The UI would still be going through UMG though.

Unreal also has a handy feature where you can make a function easily executable while you are in the editor. It’s just a simple checkbox in Blueprint, “Call in Editor” and in C++, you give the UFUNCTION macro a specifier, “CallInEditor”. This provides a button in the editor, when you have the object selected, that allows you to run the function without running the game. This functionality also extends to data assets as well.

Epic isn’t always accurate with the actual state of a plugin, so sometimes you may be worried about trying a plugin that is in “experimental” status. It can be perfectly functional, but remain in experimental status because the editor isn’t pretty for it and that’s all. Perfect example is the EQS system (explained in the AI section). It is an experimental plugin but hundreds of games have shipped with it just fine. On the other hand, a plugin could be marked as stable but still crash the engine when the wind blows. So don’t be afraid to try out an interesting looking plugin!

Asset Management

This one is quite straightforward, Godot has no real form of asset management. It has to be handled entirely on your own. In Unreal, you have the Asset Manager. Using this, you can have better control on what assets get loaded and unloaded. You can even only partially load an asset if you need just one piece of information from it. For example, let’s say you just wanted the icon and description of all of your swords in a game. In Godot, you’d have to have some way to store just that information, or load the entire asset and get the information. In Unreal, you can just query the Asset Manager for just that information once you set it up. Now, this won’t be that big of a deal if you’re just doing small games, but it comes in handy when you have to deal with larger games or just tons of assets.

When you go to move an asset in Unreal, after the move happens, make sure you right click on the folder and select the option “Clean up redirectors”. A redirector pretty much tells the engine that an asset or class moved to a new location or has been renamed.

AI

Another one that is pretty straightforward, Godot has no AI tooling to help build your game. You have to write everything yourself. Unreal provides a Behavior Tree implementation out of the box, as well as a system to query the environment for information. It also provides a debugging tool to examine numerous properties of your AI agent. It has a navmesh and multiple avoidance algorithms implemented. Godot has had a navmesh in the engine for a long time, but it was largely useless due to the lack of agent avoidance. It has improved in this area recently in Godot 3.5 and Godot 4 with the addition of the NavigationServer. But the way to actually process the AI agent and debug issues with it is still largely non-existent. Unreal provides a Visual Logger that can record the state of your agents as you’re playing your game. You can then playback this information to see the state of the agent at specific points in time. They also have a new State Tree tool that is a combination of a State Machine and Behavior Tree. It is still in its infancy, but you’re welcome to try it out. It has some cool property binding features. You can easily replicate the State Tree setup with Godot though, just by using nodes and the Scene Tree.

The Environmental Query System (EQS) is the tool that provides a way for your agents to query the environment to make decisions. It works by scoring things in a location and then selecting whatever has the highest score. You can use this as a way to find cover for the agent or if they should pursue a target or use a ranged attack. Could also use it to find likely locations to investigate if they lost track of their target.

Unreal also features a perception system that can help bring believability to your game. You can set up an agent to appear to have things such as sight and hearing. So when they “see” the player, they can respond.

Profiling Tools

Unreal reigns supreme here. You can profile practically everything in your game and even hook in custom profiling/debugging information to the existing tools. Godot’s profiling has traditionally been quite lackluster in this regard, however, in 4.0 they did introduce adding in custom profiling tools. While that is nice for your game stuff that you care to track, it still isn’t enough when it comes to profiling code you didn’t write.

UI

In Godot, you would mostly use Control nodes to build out your UI in the SceneTree. The workflow is virtually no different than if you were building out a regular scene. In Unreal, you are mostly going to be using UMG (Unreal Motion Graphics). As stated before, it is a wrapper around Slate, the underlying UI framework. It makes it more Blueprint friendly. The way it generally works is that you build out your UI with widgets in a hierarchical kind of way. Kind of like how you’d do it in Godot. Then you can also script custom logic for the entire UMG widget (that’s what happens when you create a new widget, you’re creating an entire widget). You can then use these widgets in other widgets. Mirroring how you can compose UI scenes on top of UI scenes in Godot. The overall workflow in both engines are about equal, it will just come down to building familiarity with the provided widgets and scripting out custom functionality.

With C++ and Slate, you can build entirely custom UI that isn’t typically supported by UMG. You can even build your UMG UI in C++ and do the logic in C++, while designing the look in UMG.

Networking

This is a big one, because it is so intrinsically tied to your game. There is no surprise here that Unreal makes this just outright easier in many regards. Be it testing your game or simulating network conditions (still no substitute for REAL networking conditions!). Networking is baked into the Gameplay Framework, so support for it is quite good. In Godot, to update a variable value from the server to the client, you would use the RSet() method from the server, or you could RPC the value. In Unreal, you just select from a dropdown that the variable replicates and you’re more or less done. You would just change the value on the server and Unreal will handle getting it to the clients. The engine handles updating things based on some configuration settings and gameplay conditions. Now, in Godot 4, this has changed a bit. They have removed RSet() and introduced the MultiplayerSynchronizer node. This serves the same purpose as the replication logic from Unreal. In Unreal, to properly spawn an object in a networked environment, you would spawn it on the server and the engine handles spawning it on all clients as well. In order for this to work, you would need to make sure the actor has the “Replicates” checkbox active. In Godot, you have to manually RPC this request from the server. Though, again, in Godot 4 this has changed. They have introduced the MultiplayerSpawner node that effectively does the same thing.

Unreal also features a fairly robust relevancy system (sometimes referred to as interest management) where clients won’t receive updates from the server if they’re too far away. This can help with networking bandwidth and lower server costs if you are using a dedicated server.

Unreal uses a Server-client architecture. This is one of the most common setups and Godot has support for this as well. Godot does provide better support for doing P2P setups though. Once you do that in Unreal, you are entering a custom networked setup, so you lose out on a lot of the automatic handling the Unreal does for you. That’s not to say that you can’t do it in Unreal, it’d just require some elbow grease.

In Unreal, you are also not expected to have a separate project to handle server setups. In Godot, it is far more common to have one project serve as the client code and another project to serve as the server code. This separation can lead to frustrating redundancy. However, in Unreal, you do need to build from source in order to get a dedicated server build.

Here are some really good resources to get started with networking in Unreal. The first one is generally considered the holy grail of resources and is often referenced by the community:

Audio

Unreal has a lot of tools to handle modifying audio within the engine itself. You can make a lot of adjustments just through the Sound Cue asset itself. You also, in Unreal 5+, have the option to do some really cool modifications/authoring through MetaSounds. I’ve even seen some people create their weapon sounds through MetaSounds alone. No 3rd party package needed! In Godot, you mostly have to rely on external tooling to handle audio, including adding in some additional effects. I’m not an audio engineer myself, so I can’t give super accurate testaments to either engine in this regard. I just want sounds to work and they work fine in both engines. Much like the rest of Unreal, in this department, it just has overall more tooling to leverage to your advantage.

VFX

Godot has some new shader toys to play with in 4, as well as some new features for particles. In Unreal, this is handled through Niagara and their material system. Writing a new shader in Unreal involves either doing some custom thing with materials, or writing the raw HLSL code. Godot uses a simplified shader language to accomplish writing shaders. Though it also has a visual shader language, Unreal’s material system is far more mature. A vast majority of your shaders are going to be through the Material Graph in Unreal, where as in Godot - you could do it in either visual or text form. Doing it in text form in Unreal is…annoying.

Both engines also support compute shaders (Godot introduced it in 4).

Niagara is more complicated than Godot’s particle system, but it is quite composable. This video does a pretty good quick overview of it Niagara in 300 seconds. The overall idea is that you build smaller pieces of the puzzle and then compose whole effects from these pieces. Making things quite reusable. Niagara even has some really nifty gameplay interaction features that I’d welcome you to explore.

Gameplay Framework

I’ve mentioned this a few times now and you’re probably wondering what it is and how it relates to Godot. Well, in honesty, it has no direct comparison to Godot. The Gameplay Framework is what Unreal calls all of its systems that are in place to help you build games faster. Such as actors, controllers, game modes, static libraries, so on and so forth. This is where a lot of people get lost because they don’t understand which class to use in which given scenario. Honestly - you can ignore A LOT of it and still work with Unreal almost like a blank slate. I will try to break down the important pieces. Keep in mind, some of this doesn’t really matter in a single player game.

We’ve already been introduced to the Actor, which is the base class that can live inside of a map. You also have the GameMode class (which is just another Actor by the way) which dictates the rules of your game. This is more important in a networked game rather than a single player game, but the GameMode only exists on the server. Client’s do not have access to this. The GameMode will handle logging a player in (even in single player games, a login is just like a player signing into the map more or less), player spawning logic, various default classes, connection logic - really just anything that is important for the setup/teardown of your map’s rules. Notice that I said “map”. GameMode’s are tied to the level that they are assigned. This would be a good place to put how many points it would take to win a round, for example.

Sometimes, players need access to the information in the GameMode. This is why the GameState exists. It exists on both the server and client. It is meant to track the state of the game. Such as how many points a particular team may have or whatever else you may deem as worthy. It too is just an actor. This class can largely be ignored in a single player game if you so choose. I tend to tell people to look at the GameMode as the “Game Controller” and the GameState as a way to read information from it. Again, really only relevant for a networked game.

The framework has a system known as “possession”. Only Pawns can be possessed. They are possessed with a Controller. Think of the Controller as the brain and the Pawn as the body. Each player has a PlayerController and input will be processed through this. Now, this doesn’t mean you have to put all of your input in the controller. Typically, you want to put your Pawn agnostic input in the controller. So something like pausing the game. You want to put pawn specific controls in the pawn itself. Such as moving the character. Think about Grand Theft Auto. You can run around on foot and drive around in a car. Your on foot character would have its own movement handling code and your car would have its own. When you enter the car, you change possession from the character to the car. As you get more experience, you’ll strike your own balance, but this is a good guideline. You’ll even come up with tricks to fake possess multiple pawns.

You also have what is called the PlayerState. Now, this can be ignored in single player games for the most part. In a networked game, clients do not have access to each other’s player controllers. But sometimes, you want to rely some information from one client to another. That’s where the PlayerState comes in. Something like their individual score or what team they’re on would be good candidates to be placed in the PlayerState.

Next up is the Character class. You’ll most likely be working with this a lot throughout your time in Unreal. It is expected to be used with humanoid skeletal characters. It comes with a CharacterMovementComponent (often just referred to as CMC) that has a lot of built-in functionality. Especially helpful in a networked game. This includes client correction. It is a beast of a component that can be tweaked to get the right settings. This class is really just a specialized version of the Pawn. You can completely ignore it if you want. That is part of the beauty of the framework, you don’t have to use most of it, contrary to what many people believe. If you want, you are free to build up your own version of the Character class. The framework is just here to help with some common scaffolding work.

This leads me to wanting to touch upon the idea of Movement components. In Unreal, it is very common for you to move things around utilizing movement components. All these are, are components that handle the locomotion of the actor. Your Godot senses may be tingling, because this means that the movement component is moving the root component of the actor (similar to a child node moving the root node of a scene). But fret not, because that is the expected behavior. And to be quite frank - it should be more accepted in the Godot world as well. No, you shouldn’t just have components messing with other components all the time (or nodes messing with other nodes), but if they are purpose built and you have specifically architected it to be that way, it is perfectly acceptable. Ideally, yes, you want components/nodes to be as self-contained as possible with minimal dependencies. But in the real world, that isn’t always the best way to do something. Remember, guidelines are not rules - they’re guidelines. Understand them and know when/why you are breaking them.

One of the last important classes is the GameInstance. This will exist from the time your game starts up to the time it shuts down. So it is most like an Autoload node. By default, when you transfer from one map to another map, Unreal will destroy all the actors in that map. This means you’ll lose any data related to those actors. There are a few actors that would persist if you elect to use Seamless Travel (explained in the data persistence blog post linked earlier), or you can just store that information in the GameInstance and then retrieve when the new map loads.

This is the part where I would also like to mention subsystems in Unreal. These are singleton-like objects and the lifetime of the objects are managed by the engine. There are a few subsystems you can create, with the one that is most like an Autoload being the GameInstanceSubsystem. You can only have one GameInstance per game, but you can have as many GameInstanceSybsystems as you’d like. Each subsystem’s lifetime is tied to the type of subsystem it is. In this case, a GameInstance. So it has the same lifetime as the GameInstance. So to emulate having multiple Autoloads, you’d lean more towards the GameInstanceSubsystem.

Some helpful information on the framework:

Lifecycle Events

What I mean by lifecycle is things that the engine will call for you, in Godot’s case, things like _ready() or _process(). In Unreal, it’d be things like BeginPlay() or Tick(). In Unreal, I would encourage you to read the comment in the Actor.h file, near the top. It goes over a lot of the initilization order for actors. BeginPlay() is going to be the rough equivalent to _ready(). This is one of those cases when there isn’t an exact 1:1 mapping though. One massive benefit that Godot has is that it has a very deterministic processing order. What I mean by this is that you know exactly when a node’s lifecycle method will be called. You know that _ready() will be called on a sibling node that is lower in the scene tree. Unreal does not have this kind of determinism. You don’t know in which order Tick() will be called either. You do know in what order _process() is called however. Due to this, you may structure your scenes in a certain way in Godot that leverages this without even realizing it. So some ways that you may be comfortable in structuring your game, won’t necessarily translate over to Unreal. It is better to not rely on initialization order when it comes to referencing other actors. Now of course you can build your own little way to handle it, such as doing some kind of event bus setup. That’s up to you though.

Also, another important difference is that in Godot, you have _process() and _physics_process(). In Unreal, these are both combined into Tick() more or less. So don’t fret that you don’t see a physics version of it. With Tick() you have a few configuration options however. You can put them in different tick groups (that will tick at different times) or even change how often tick is actually called on something. I do also want to mention that with Unreal’s new Chaos physics engine, they did introduce something that is like _physics_process() though. “Async Physics Tick” I believe it is called. It isn’t fully featured at the time of this writing and has limited uses currently, so I’d say avoid it when starting out, but pay attention to it.

Level Design

Unreal has a Terrain system that allows you to rapidly iterate on your level. In Unreal 5+ it also improved the level design tools with the introduction of Cube Grid. This allows you to build out a level really quickly so you can test out your ideas. It also has a couple other modeling tools that can help with quickly iterating on a level, but the two big ones are the Terrain system and Cube Grid. In 5.2, they’re also introducing a new procedural generation tool that appears to be modeled after some procedural tools from Houdini.

In Godot, you have to build out all of your own tools if you’re using 3D and only recently have they come around to the idea of having a Terrain system, though it still won’t be a part of the engine. Instead it is being proposed to be built as a GDExtension. There are a couple community plugins for terrain, as well as the wonderful Qodot plugin. This plugin allows you to import quake maps into your project. This means you can use something like TrenchBroom to build your maps.

Unreal also has level streaming and support for automatic loading/unloading of your world grids with World Partition. Though, that is still pretty new and many people have been running into issues with it. So your mileage may vary. It is intended to replace the older World Composition system. The way both of these work is that you stitch together a bunch of maps (kind of like how you’d end up doing it in Godot, stiching together a bunch of “level” scenes) and then have Unreal load/unload the maps on an as needed basis based on some rules. World Composition was more manual in that regard. World Partition pretty much automates the process. Level streaming is a more simplistic and straightforward approach, however, it is not intended for large worlds. It’s much better utilized for small maps. That isn’t to say you can’t do some neat tricks with it for larger worlds though!

Physics

Truth be told, I can’t accurately compare these two areas because I have mostly used Kinematic setups. This is true in Unreal and in Godot. All I need most of the time is basic collision reporting and good raycasting (called Linetrace in Unreal). Otherwise, I hardly ever mess with physics at all. The only time I’ve messed with physics in both engines is when dealing with joints and ragdolls. In my experience, I’ve had less issues and better results for these two scenarios in Unreal. That’s not to say that it is better or anything like that, because again, I don’t really deal with physics.

All that said, Unreal does have phsyics driven animation system which can really help bring in some believability in something like hit reactions or carrying a body, etc..

Godot’s collision filtering setup is much more straightforward than Unreal’s. Using the Layers & Mask setup is quite easy to wrap your head around in comparison. The way Unreal handles it is that Linetraces (raycasts) and non-linetraces have different configurations. Each object can have a different “object type” for the purposes of collision. Then you select how this object responds to the other object types or line trace channels. You can have ignore, overlap, or block. Unreal will respond with the lowest blocking one.

Ignore is exactly what it sounds like - it ignores this object/linetrace type. Overlap would be just like if you wanted to use an Area node. Block is for…well blocking collision. Unreal also has two different events for collision. OverlapBegin/End and Hit. OverlapBegin/End works exactly how the Area node works. Hit will fire off for blocking collisions. In order for these events to fire off, they must be turned on in the details panel.

Let’s go through a quick contrived example. Let’s say you have an object type, say “Door”, for all of your doors and then one called “Ball” for all of the balls. You want the door to block everything, so you set it to block everything. In your ball, you set it to ignore doors. The ball will go through the door because the lowest blocking value is ignore due to the ball’s configuration.

Overall, it can take a second to wrap your head around it - but this old bog post is what really helped me understand it Collision filtering. One really neat thing that Unreal supports is collision presets though. This allows you to quickly set up configuration for common types. For example, you may want to have a preset for all interactables. So you just set up the configuration in your project settings and then when you want a new interactable, you just select that configuration and it sets all the channels according to your preset.

C++ or Blueprint

Honestly, both. The engine has been transformed to support this workflow. There are some things that Blueprint is better at than C++. Most notably, doing something across multiple frames. In Unreal land, this is a “latent” node. There isn’t a good answer on how much Blueprint you should have or how much C++ you have either. It is entirely dependent on the game and the team. So don’t fret if you’re not doing it right according to anti-Blueprinters. They’re wrong anyway. You can read another’s opinion on this topic in Laura’s blog post. That whole post is still good info as well, even if it is talking about going from Unity to Unreal. I would recommend Laura’s entire blog really. As a matter of fact, this is the post that inspired me to write one for Godot to Unreal.

Closing Thoughts

Overall, Unreal is a big engine that has all the bells and whistles. You don’t have to master everything all at once. This is what trips people up most of the time. Each area of Unreal typically has a dedicated window and generally has all of the tools you need to use that area of the engine. Much like most software, 90% of what you see, you won’t use. But when you do need it, it is quite nice to have. That isn’t to say that it is a perfect piece of software by any means. It certainly has its own problems and drawbacks. My advice will always end up being the same, pick the tool that makes the most sense for you.

Here are some really helpful resources for Unreal overall:

  • Tom Looman’s Blog - Former Epic engineer and longtime user of Unreal. Was using 4 before it went public.
  • Laura’s Blog - Very technical and practical engineer (definitely check out her C++ speedrun post).
  • Benui - Seriously, explore this site. It has a lot of good information on the UI side of Unreal, as well as what the community mostly uses to look up UPROPERTY and UFUNCTION specifiers, because Epic’s docs on it is lame.
  • Common Issues in C++ - Covers a lot of the most common things the community sees from beginners.

Categories:

Updated: