Death trap: Casting to custom BP-objects in MacroLibrary macros
The pitfall above is a “friendly” kind of problem, because it doesn’t disable your project in general, it just silently fails to do something, repeatedly, until you fix it, so it’s not a big deal. The death trap I’m about to describe now however, is quite a bit more nasty, because it can cause all sorts of erratic in-editor crashes or even prevent you from opening the project at all, forcing a roll-back to a previous revision and very likely a pending overconsumption of migraine medication.
Here’s the scenario: You have a custom player controller class, ThePC_BP, based on PlayerController.h as per usual. In this class you have a function called MakeStuffHappen, which makes stuff happen. It works fine.
In your level there’s a small zoo of different custom blueprint actors that sometimes need to call ThePC_BP::MakeStuffHappen for whatever reason. These may be stand-alone blueprints derived directly from Actor or Pawn, or maybe “second generation” child-blueprints derived from some custom base class that you have created.
At any rate, to call ThePC_BP::MakeStuffHappen, they need to call GetPlayerController, then cast the reference to ThePC_BP, and then they can call the function in question.
After a while you notice that this little chain of nodes shows up in lots of places. To clean things up, you decide to create a Blueprint MacroLibrary, in which you create a macro called GetThePC. It simply performs that little sequence of calls and returns a properly cast ThePC_BP link along with two execution pins, one for Success and one for Failed (in case the cast didn’t work for some reason).
You start placing this macro everywhere in your Blueprints where you need a link to ThePC_BP, and it seems to work fine, and your graphs are much cleaner and easier to read. Awesome.
Now here’s the kicker: at some point, maybe today, maybe next week, maybe when you place the thirteenth instance of that macro somewhere, maybe when you create a new child BP based on a BP that uses the macro - your project may suddenly fail to open. It will just crash on launch. Or, if you are lucky, nothing bad happens at all. If it goes south, a roll-back to a previous revision seems to be the only way to get back on track.
I have tried to create a minimal reproduction case for this particular problem, but so far it’s just completely random.
SUMMARY: Using a macro in a MacroLibrary to cast something to a custom BP class is potentially catastrophic.
SOLUTION: Just don’t do it. Come up with another way to do whatever it is that you are doing.