Thanks for letting me know, that is inconvenient. I saw this post a while ago but I know little more than I did in my PostEditChange topic. If I remember correctly, that post I made was specifically because I was writing data from an external editor as a form of automation. This is not something you normally do. I was not willing to set all properties manually because I had updated data available in CSV format, so I needed to inject the data.
Can you describe in short what specific goal you need to achieve in the editor? Because there might be other ways to get there. Injecting your own logic during editor events / editing / saving has been a hacky process for me which I like to avoid.
Gardian206 explained a lot already. Many things are better done outside of the constructor (or wouldn’t work otherwise) and many things can only be done when the game is actually running.
The constructor is only meant to set up the class itself. Any values set there will be the default values to the editor and to blueprints. The constructor in c++ must not be confused with the blueprint construction script, which is not an actual constructor and has very different behavior. Even in the blueprint construction script some things are not available, like certain debugging features.
Other than that, you are working with UObject* pointers. These are of the “hard pointer” types, meaning that the object they point to must exist. When this object is deleted or not referenced as UPROPERTY in unreal engine the hard pointer will automatically be nulled.
When you work in the editor, there are multiple objects for what you think is the same thing, but is not. There are instances on the editor level, instances copied from the level to PIE, and instances for the asset editor per asset. Here I lack accurate information / documentation (which I would love to have), but I think you are editing a temporary object which is trashed, or you are setting pointers to objects which stop to exist. I hope to be of more help if I see what exactly you try to achieve.
When you want to modify a class and save it as a default, you want to be saving for what is called the CDO (Class default object). This serves as a template for all new instances. This is what happens when you edit a class through the editor windows the normal way, but misbehaved when I attempted to inject data in my post you linked.
In my experience, if you can do something with components then do it. Place an actor on the map in the editor, attempt to avoid doing things with it in the blueprint constructor (try to do everything after BeginPlay).
In the editor you can add components to an actor and in the level you can edit the instance to move the components around. Then during BeginPlay:
SpawnerActor::SpawnThroughComponents()
-- SpawnPositionSceneComponent::SpawnAtLocation()
-- SpawnPositionSceneComponent::SpawnAtLocation()
-- SpawnPositionSceneComponent::SpawnAtLocation()
Doing so makes your work 100% compatible with the implementation of UE and you can skip storing pointers. The only pointer that is mostly save to be set in the editor is of the soft type, when you want to load an object yourself. The soft type acts more like a path which you can load on demand, providing a newly created object and a new hard pointer. the use case for that is when you want to provide a “SpawnActorClass” in the above example without having an instance of that class / actor and without having it loaded in memory already.
Please correct me if I’m wrong. I’m not entirely sure about this. When you create a hard pointer in blueprints the entire class is loaded into memory even if you don’t access the property. During the unreal editor splash screen (initial engine and module startup) and apparently just when running Visual Studio a lot seems to be loaded and running already.