How to edit default values of a UPROPERTY of an instance of a widget programmatically and not lose it on compile

Hi! This is my first post, so let me know if there’s too few information or if too few context.

Basically, I have a widget with an FColor property that’s generated from a static function. I want this static function to only run once in the NativePreConstruct. So I’ve overridden that function in the widget child class. The property is set once by having a second bool property that gets turn back to false during the PreConstruct to make it more of a exec function button in the blueprint properties. Like so :

void UMyWidgetClass::NativePreConstruct()
{
	Super::NativePreConstruct();
	if(bReloadMyColorProperty)
	{
		MyColorProperty = UUtilityClass::MyColorGenerationFunction();
		bReloadMyColorProperty = false;
	}
}

Up to this point, everything works, the value is set but only until I compile in editor. Then the value returns to it’s previous value. I’ve looked into CDO and how when you edit them all class instances defaults get overridden by the change, but I only want to edit the default value of the instance I’m working on.

In summary, I want to edit the value of a UProperty during PreConstruct (or any non-runtime event) and for it to stay set to the given value after compiling. I’d assume it’s doable since you can change the default values of the class this way, and those stays after compiling.

Could it be that you’re not calling Supper::NativePreConstruct() the parent implementation has some code.

I’m calling it, just forgot to add it in the code snippet.

Do you want to assign values to some Widget Instance properties by calling UUtilityClass::MyColorGenerationFunction(), then modify the implementation of static functions, and then apply them to other Widget Instances?

The goal of this is more of being able to run once a utility function to generate a property value that would be costly at runtime. It doesn’t have to be a static function from a utility class, it could be a UMyWidgetClass function. I just need the changes to be permanent like when you edit the CDO, all class instances receive the new value and that persist post-compile. I need that but for a single instance at a time.

When I build cached data for any UObject derived class I use PreSave and BeginCacheForCookedPlatformData, the first one runs when saving and makes sure you can test in the editor while the second one runs when cooking to make sure the data is up to date.

#if WITH_EDITOR
	virtual void PreSave(const ITargetPlatform* TargetPlatform) override;
	virtual void BeginCacheForCookedPlatformData(const ITargetPlatform* TargetPlatform) override;
#endif
1 Like

This seems like a step in the good direction, it does allow my tool to permanently change the properties of the object instance but like you said, only on save.

Is there some kind of “PreCompile” that I could override to prevent it from reverting the changes applied onto the widget?

I have been searching for exactly that thing, sort of like OnConstruct but for all blueprints and not only actors. Unfortunatelly I didn’t find it, if you have the engine source you can probably add it yourself. For cases where I wanted to see the cached data in game without having to save every time I used the FEditorDelegates::BeginPIE delegate additionally (bind it in the constructor), it works but freezes the editor for a bit when you need to do heavy operations every time you start PIE.

Alright I’ll look into that one, I’ll keep the thread open for a bit in case someone found a workaround.

From what I’m reading everywhere that slightly mention what I’m trying to accomplish, Archetypes, which are some kind of instanced copy of the CDO, are what were editing in the editor when we change properties of an instance of a UObject. I’m currently looking into some way to change them and “apply” or “save” the changes.