For last week, I’ve been working on an Actor Blueprint which I’ll use do design some action and bake it into an asset. Thus I use virtual functions like OnConstruction, PostEditChangeProperty and etc…
While I was using them I was having weird bugs and crashes about them. For example, I was inserting an element to a TArray which index is out of bounds at OnConstruction script. Normally, insert function should resize the array if index is greater than arraynum. So when OnConstruction is called after a Property change (like after I change a value in details pane) it works as intended. But if I press the compile button, that insert will give me an access violation error at the memmove function.
While trying to debug what is going on I realized OnConstruction script and other kind of scripts do not get called for once. At least from what I understand when I open an Actor Blueprint Editor, there are like 3-4 instances of the Actor which has different flags and properties.
So these are the calls for OnConstruction function when you first open an Actor Blueprint Editor from content browser. I may have misremembering the actual function calls amount but you will get the point.
2 OnConstruction calls made. One call cames from Thumbnail (somehow) and spawns a preview actor. Other one comes from some kind of Blueprint base class and spawns a preview actor. Both of those have Package Names as Engine/Transient and their Package folder name is none.
These are the calls for OnConstruction function when you change a property from details panel. I may have misremembering the actual function calls amount but you will get the point.
5 OnConstruction calls are made. The all of the package flags and properties are same for all of them. Their difference occurs at their object flag. 2(3?) of them has only RF_Transactional flag. 3 (2?) of them has RF_Transactional and RF_Transient. Also 1 one of them only gets called when the Viewport tab is open on Editor. I believe that is the actor object that responsible to get displayed in the viewport (I have no idea why they needed to separately create it).
These are the calls for OnConstruction function when you when you press compile button. I may have misremembering the actual function calls amount but you will get the point.
First 2 OnConstruction function calls occurs. Both of them have only RF_Transactional flags. Later “Compact Hash” log gets displayed on screen. Which makes me think that those 2 OnConstruction calls are the objects that are created to get held in Transaction buffer before compilation.
Later 5 OnConstruction calls occurs again. That 5 calls are exactly same with 5 calls that are occured when you change a property from details panel. But 2 of that 5 calls are called at the previous objects that I think that they may be created for transaction buffer. I am certain about that because I hold a counter integer for all calls.
Other than that I think the reason of 2 number repating is one call is for CDO and one call is for the instance we see in editor.
Also another weird thing is when I call GetPackage() and reach some package properties on all of that OnConstruction calls, all them have Package Name as “Engine/Transient” and IsPackageEmpty() returns True for all of them.
But when I handle that Package checks from PostEditChangeProperty, one more package appears with the PackageName as the path of the asset. Also that package is not empty and the “this” object that responsible that PostEditChangeProperty call has flags as RF_Public, RF_MarkAsNative, RF_ClassDefaultObject, RF_WasLoaded and RF_LoadCompleted.
So what the heck? What is actually going on behind these calls? How does this makes sense? What would be the safest way to do any checks before OnConstruction or other virtual functions? Thank you for your time and interest!