I like the 3rd option but I cannot see overridable equivalent, event or function on blueprint side. But I can imagine having BlueprintImplementable init function I could then invoke e.g. from PostInitializeComponents to keep it clean and organized.
The 2nd option (moving Super::BeginPlay at the end) might not be a good idea in my opinion. Technically speaking, I believe the parent class should not assume about implementation details in class that will inherit from it. Super::BeginPlay at the end may already change the state of the parent in a way the parent is not expecting.
I’ll try out PostInitializeComponents - thanks for pointing that out.
Or in the C++ class moving the Super::BeginPlay() at the end of the BeginPlay() function solves the order issue:
But as a software engineer this looks terribly wrong. Using another function other than BeginPlay() feels like a workaround for a bug in BeginPlay (same for moving it the Super::BeginPlay() to the end), as BeginPlay is widely used in tutorials (including Epic’s) and also in generated c++ classes.
This looks like a bug to me.