Modified property value is not applied after reload

It may be even a bug since I don’t get why it should work this way.

It will be hard to explain what problem I have but I’ll try. I have a c++ scene component with constructor, OnRegister function and few properties. Component in OnRegister function creates TextRenderComponent and sets it text to value of DisplayText property (in c++ its default value is NPC). This property is editable in editor. I also added PostEditChangeProperty function so I’m able to update text of the created component when user changes property value. So I changed text in editor to “DefaultNPC”. Problem is, that when I restart editor, I get text component with default text (NPC). I added some log function to constructor (it’s added at the beginning of the constructor, before I set default values):

UE_LOG(LogTemp, Error, TEXT("construct, text: =%s="), *DisplayedText.ToString());

And to OnRegister function:

UE_LOG(LogTemp, Error, TEXT("register, text: =%s="), *DisplayedText.ToString());

And after I load project I get this order of messages (some engine messages are replaced with “lots of lines”):

SourceControl: Info Source control is disabled
SourceControl: Info Source control is disabled

LogTemp:Error: construct, text: ==

LogObj: 26769 objects as part of root set at end of initial load.
LogUObjectAllocator: 5498136 out of 0 bytes used by permanent object pool.
LogEngine: Initializing Engine...

----lots of lines---

MapCheck: New page: Map Check
LightingResults: New page: Lighting Build
LogParticles: Destroying 0 GPU particle simulations for FXSystem 0x0000000018566200

LogTemp:Error: construct, text: ==
LogTemp:Error: construct, text: ==
LogTemp:Error: construct, text: ==
LogTemp:Error: construct, text: ==

LogAIModule: Creating AISystem for world ExampleMap

LogTemp:Error: register, text: =DefaultNPC=
LogTemp:Error: construct, text:  ==
LogTemp:Error: register, text: =NPC=
LogTemp:Error: register, text: =DefaultNPC=

LogEditorServer: Finished looking for orphan Actors (0.000 secs)
Cmd: MAP CHECKDEP NOCLEARLOG

----lots of lines---

LogContentStreaming: Texture pool size now 200 MB
LogRenderer: Reallocating scene render targets to support 856x616 (Frame:2).
LogTemp:Error: construct, text: ==
LogOutputDevice: === Handled error: ===

----lots of lines---

ntdll.dll {0x000000007789b981} + 0 bytes

LogTemp:Error: register, text: =NPC=

LogOutputDevice: === Handled error: ===

----lots of lines---

ntdll.dll {0x000000007789b981} + 0 bytes
LogTemp:Error: init, text: =NPC=
LogAssetRegistry: Asset discovery search completed in 19.5490 seconds

I have only one actor on scene so I don’t understand why there are so many construction calls but it is not the problem. As you can see from the log, at some point component gets registered with property that I set up in defaults for each instance in level (DefaultNPC) but then c++ constructor gets called again and text component text is reset. But blueprint properties are saved (so if I open defaults tab for the component - it still has “DefaultNPC” text in it).

Also I noticed that this happens only if I create blueprint (for example, character) and add my component to it. But if I use level directly (drop there something, for example empty character) and add my component there (without creating blueprint) then everything works correctly. After I reload editor - text is still in component and C++ constructor is not called after everything is inited.
After some more investigation I’ve found that it’s not actually C++ value (NPC) that I see after reload. It’s default bluerpint value. So if I change in blueprint defaults (in blueprint editor) NPC to NPCblueprint, then after reload I’ll see that TextRenderComponent shows me “NPCblueprint”.

So the main question is - how can I set not blueprint default value, but edited value? One that I edit in level for each instance of blueprint.

Of course I can add function that will be setting everyting and then call it in construction script of blueprint. But I want this to be less manual. So I can change something only in C++ and don’t have to add anything to blueprint.

Well, I added extra function RefreshComponents where I set text of the TextRenderComponent to value of my property. And call it in construction script of the blueprint. But it still uses blueprint defaults, not edited defaults for each instance. So now I don’t have even manual solution for this bug.

Call to function in BeginPlay of the component sets text fo the TextRenderComponent to edited defaults for each instance. But this is beginplay, I want it to set text in editor, before I press play. So I can work in level and see relevant information.