Ever since my first contact with Unreal Engine I have been asked this question: When do you use C++ or Blueprints? Which one is better? Which one is faster?
Well, on this post I am going to try to answer all these questions and a couple more, but first I am going to set the foundation for it and talk a little about what they are and how they work behind the scenes. Hopefully by doing that the answer to the above questions will come easy.
One thing to be said and I think it should be said at the start, there is no silver bullet or one “right answer” that is going to fit every single project out there. But hopefully by the end of this article you will have more information to help you with your design choices in your projects.
Let’s talk a bit about C++
People are often very scared of using C++ in Unreal Engine and the reason is because pure C++ requires a wide range of low-level knowledge, having to take care of cleaning up memory, taking care of a build toolchain and a real understanding of what system programming is.
But the fact is that in Unreal Engine you don’t really use pure C++, the same way that in Unity you don’t really use pure C#.
C++ in Unreal Engine and C++ in the “real world” are two completely different beasts. — Me
And because of that writing C++ code in Unreal Engine is way easier than outside of it.
But it is important to say that it is still the same language, so when people say “Unreal C++” it’s not actually a modified version of C++ itself, but in fact an extensive game-specific API built on top of good old C++.
The Unreal Engine C++ API provides a number of low-level mechanisms to make your life as programmer much easier. I won’t go into too much detail on each one of them here otherwise this articles would turn into a book, but some of them are Reflection and Object Handling with Garbage Collection happening under the hood. These “features” work with everything that is marked as U-SOMETHING: UCLASS, UFUNCTION, UPROPERTY. Basically every object in the world is based on the UObject class, which is automatically garbage collected. Check Basic Class Structure.
Unreal C++ also provides libraries supporting math, vectors, strings (with support for text localization) and many other standard useful things. Just to make development easier, so game programmers do not have to reinvent the wheel every single game.
Unreal C++ API is commonly considered as “halfway to the simplicity of scripting languages” — in the perspective of full-time programmers. It’s still C++, the entry barrier is higher than any scripting language or C#.
What about Blueprints?
Blueprints were first introduced in Unreal Engine 4 and the short explanation is that Blueprints are a way to create a UCLASS without the need to actually write C++ code. When you create a new blueprint in the editor, you will have to extend it from some other class, that being a native C++ class or another blueprint.
But of course there are other basic design differences.
For one Blueprints nodes run in a Virtual Machine (VM) that enables the nodes to call native C++ functions. But that comes at a cost, relying on a VM to translate Blueprint node into native C++ can potentially slow your game performance’s. A lot of times this cost isn’t really noticeable and you can bear that cost, but there are times when you would want your game to run as fast as possible and you will have no choice but having at least parts of your project in native C++. And although this is not an exact science, you have tools to help figure it out what points to focus on like the Profiler Tool. And even tools to help convert some of your blueprints automatically to C++ code during packaging, like Blueprint Nativization.
Ok, but what are blueprints?
Well, blueprints are nothing more that a Visual Scripting Language, focus on Visual. With blueprints you basically use these nice looking nodes to do all your programming and logic. With blueprints you can add, edit and customize components, implement custom logic, create and respond to event and interactions, define custom variables, handle input and basically do pretty much the same things you would do with C++, with some limitations only. For instance there are something that as of the writing of this post you cannot do in Blueprint for example the setting up of the Gameplay Ability System.
C++ vs Blueprints
- Faster runtime performance: Generally C++ logic is significantly quicker than Blueprint logic, for reasons already discussed.
- Explicit Design: When exposing variables or functions from C++ you have more control over exposing precisely what you want, so you can protect specific functions/variables and build a formal “API” for your class. This allows you to avoid creating overly large and hard to follow Blueprints.
- Broader Access: Functions and variables defined in C++ (and exposed correctly) can be accessed from all other systems, making it perfect for passing information between different systems. Also, C++ has more engine functionality exposed to it than Blueprints, for example as already mentioned the Gameplay Ability System.
- More Data Control: C++ has access to more specific functionality when it comes to loading and saving data. This allows you to handle version changes and serialization in a very custom way. One important note is that Enums and structs that are defined in C++ can be used both by C++ and Blueprints, but user structs/enums cannot be used in C++. So a good recommendation would be to implement critical enums and structs in C++.
- Network Replication: Replication support in Blueprints is straightforward and is designed to be used in smaller games or for unique one-off Actors. If you need tight control over replication bandwidth or timing you will need to use C++. Hence why most large studios and project will do all their networking in C++.
- Better version control: C++ code and data (as well as config and possibly custom solutions) is stored as text, which makes working with version control, diff and merges a lot easier.
Some of the cons of C++ are also the pros of using Blueprints, so I’ll mention those below except for the fact that C++ have a much longer learning curve and although I still think that people should learn the basics of general programming and object oriented programming concepts before they go into Blueprints, that process in Blueprints is a lot faster.
- Faster Prototyping: Usually creating a new Blueprint class and adding variables and functions is faster than doing something similar in C++, so prototyping brand new systems is often faster in Blueprint.
- Faster Iteration: It is much quicker to modify Blueprint logic and preview inside the editor than it is to go to your code editor, editing the code, recompile the game, and hoping the HOT RELOAD won’t screw things up. So blueprints are basically more tweakable most of the time.
- Better Flow Visualization: Sometimes, although this one can be very personal, It can be complicated to visualize “game flow” in C++, so it is often better to implement that in Blueprints (or in custom systems like Behavior Trees that are designed for this). Delay and async nodes make it much easier to follow flow than using C++ delegates.
- Designer and Artist friendly: Designers and artists without specific technical training can create and edit Blueprints, which makes Blueprints ideal for assets that need to be modified by more than just engineers.
Yes, I did mention that Blueprints can be better for flow visualization, but if the developer is not careful and organized enough it can easily turn into very messy code.
Also as mentioned already, Enums and Structs created on Blueprint can only be accessed in Blueprints, so if you plan to move your gameplay logic to C++ over time it is recommended to implement at least critical Enums and Structs in C++, at least if more the one or two Blueprints use them.
Another point against Blueprints is that as of writing this article there are still a couple of things that you can only do it in C++, for example the setting up of the Gameplay Ability System.
And last but not least, there is performance issue that although is not always an issue and it can be circumvented by thing like Blueprint Nativization, I still have to mention it.
So, which one should I use?
Like I mentioned in the beginning of the article, there is no Silver Bullet. There are a lot of things to consider when choosing to work with Blueprints vs C++. From the expertise of the people working with it, how confortable is the team with C++ and Blueprints. What phase of the project you are in? What are the most important pillars of the project? What type of project plays a huge role in here also? What features and mechanics will your game have? Well, and the list goes on.
The fact is that Blueprints and C++ excel in different areas, and the one that should be used is the one that offers the most support and comfort to whatever needs to be accomplished.
What is my usual approach?
Again, it varies from project to project, but here are my two cents on the matter.
- For the end product I always try to do at least all my base classes, implementations and systems in C++ so I can then extend it in blueprints. I fell like this is a very efficient workflow.
- Related to above point, casting to Blueprints can sometimes be very expensive, so for this reason I always use native C++ base classes or minimal Blueprints base classes that define important functions, components and variables and then make your heavier Blueprints as child classes of those.
- It is absolutely fine and recommended to prototype systems and features in Blueprint, since Blueprints are much faster to iterate.
- I also try to do all my networking and event related logic in C++ and for the event surface them in Blueprints as needed.
- Whatever you use, keep it well documented and commented.
- For the rest, it has to be a case by case evaluation, bottom line is:
Use the right tool for the right job.
To wrap it up
On this article we started by taking a little bit of a dive into how things works behind the scenes for Blueprints and C++ so than we could talk about the pros and cons of each approach. To finalize I made sure to talk a bit about my take on the matter and my usual approach to when dealing with this topic.
I hope I was able to shine a bit of light on the subject and at least help you choosing your path on your next project.
Be sure to leave a thumbs up and of course comments are always welcome!
Top comments (0)