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.