Enforcing blueprint users to set up properties (widget references) during compilation?

I want the Blueprint Compiler to throw an error if a Blueprint is not configured properly by setting up some class properties. To do so, I implement the following method on a class deriving from UUserWidget:

void UUserWidgetCore::ValidateCompiledWidgetTree(const UWidgetTree& BlueprintWidgetTree, class IWidgetCompilerLog& CompileLog) const {
	Super::ValidateCompiledWidgetTree(BlueprintWidgetTree, CompileLog);

	if (!HasValidBlueprintDependencies()) {
		FText OutText = FText::GetEmpty();
		FText::FindText(TEXT("EditorLog"), TEXT("Widget_InvalidDependencies"), OutText);

		FFormatOrderedArguments Args;
		Args.Add(FText::FromString(CompileLog.GetContextClass()->GetName()));
		Args.Add(OutText);
		FText Message = FText::Format(FTextFormat::FromString("{0} : {1}"), Args);
		CompileLog.Error(Message);
	}
}

The validation method “HasValidBlueprintDependencies” is a Blueprint Implementable Event.
The problem is, that this method on the blueprint is never called, so the compiler will throw an error even if the method is properly implemented in Blueprints.

What is the correct way to implement this sort of validation?

Edit
Attempting to call a BlueprintImplementableEvent from c++ During “UObject::IsDataValid” also results in the method not being executed. It is simply skipped. Why is this happening?

Edit
When calling the function at a later moment (UUserWidget:Initialize) it works correctly, but this is already way too late to validate the widget.

1 Like

Bump.

Bump. I don’t get it. The documentation says you can use a UFUNCTION(BlueprintImplementableEvent) with UObject::IsDataValid, so why would the method be skipped over in c++?

Talking to myself but I figured out a few things:

The validation method is only executed from UObject::IsDataValid if the output of the validation method is not depending on a reference to another UObject like a widget from the hierarchy. This means a boolean output is read properly from blueprints. Any blueprint node before the output node seems to be skipped entirely, breakpoints are not hit and operations on invalid references do not generate an error.

The question remains… I want users to configure references to the widget hierarchy for the widget’s parent class (c++) and I want the compiler to throw an error if they don’t so that I can enforce proper configuration.

bump

WIthin your UUserWidget you can setup required widgets within, by name, and the BP compiler will throw an error if the named widget of correct type is not created by the user.

You need to simply mark the sub widget reference as a Widget Bind.
The compiler will throw an error until the user adds the widget to the hierarchy:

UPROPERTY( meta=(BindWidget) )
UTextBlock* MyNamedTextBlock;

That will make your widget always require a Text Block named exactly “MyNamedTextBlock”.

1 Like

This is really cool! Exactly what I need. Wish it was documented, would have saved me 4 days of working with BlueprintImplementable getters.