I think it can be helpful to think of the game creation process being split up between multiple people with different skills. If you create and organize your project with this in mind I think you will quickly see the value of blueprints and C++ and how they combine.
I know that many folks work alone, so it might help to think of yourself as a person with multiple roles. Self - The Level Designer, Self - The Engineer, Self - The Technical Artist etc. If your level designer wanted an N-Body Gravitational Attraction actor, you’d probably want to make this in C++ and expose only a specific set of Functions and Variables that would allow them to use the actor in the intended way - i.e. not trying to calculate 1000 actors with the classic formula
This is really no different than say, making a class in C++ and deciding what gets exposed to people that will be implementing your class. If you think of delivering small re-usable modules like this that can be consumed by various people in blueprints, I think you’ll begin seeing the synergy between C++ and blueprints.
A lot of people talk about the speed of blueprint prototyping, this can be nice especially when you’re starting out and may not have a good handle on all the classes and functions that you need. Remember you can right-click any blueprint node and “open code”. I think that once you are up to speed, the only reason blueprint might be faster to work in is because you have to completely restart the editor to add a new C++ class - this can really destroy your productivity if you’re in the middle of prototyping something. For me, doing vector math in blueprints takes more effort to read, write and diff, also I can’t do pointery stuff like
*tank = FMath::Max(*tank - LaserChargePerTick, 0.f);
so I naturally gravitate towards the C++ end of things.
Sometimes it makes sense to do a quick implementation via blueprint, sometimes it doesn’t. I often make the decision based on how complex the thing is and also whether or not I want people messing with something. If I think my level designer might accidentally break something by modifying a blueprint, I’ll encapsulate that critical functionality into a C++ class and expose only a few tuning variables that I know can’t break things.
As you use blueprints and code, you’ll probably find your own happy medium. I think most of us that are heavy C++ users still use blueprints for object composition. It seems easier to compose a complex set of objects in blueprints and then get references to those in C++ rather than compose a complex object in C++. In the first case you have a set of named sub-components that you look for, in the 2nd case you have hard-coded asset references. You can change the first without recompiling, although you can still run into issues if you change your object drastically.