Hi!
If you create a simple Blueprint utility function, for example:
UFUNCTION(BlueprintPure, Meta = (AutoCreateRefTerm = "ObjectClass", DeterminesOutputType = "ObjectClass"))
static const UObject* GetDefaultObject(const TSubclassOf<UObject>& ObjectClass);
{
return ObjectClass.GetDefaultObject();
}
You can then try to use this function in a Blueprint, and at first everything looks ok - if you change the class referenced by ObjectClass, then the type of the output pin changes accordingly. For example, using the GetDefaultObject node above, you can drop it in a graph and set the ObjectClass to e.g. Actor, and then read the value of the Actor Hidden In Game variable from the CDO by dragging from the Return Value pin.
If you however compile this blueprint, you will get the following errors in the log:
Can't connect pins Target and Return Value : Actor Object Reference is not compatible with Object Reference.
Can't connect pins Return Value and Target : Object Reference is not compatible with Actor Object Reference.
Invalid pin connection from ' Return Value ' to ' Target '. You may have changed the type after the connections were made.
So during compilation, the type of the Return Value pin flipped back to UObject instead of AActor.
I debugged a bit into this, and the culprit seems to be in UK2Node_CallFunction::InnerHandleAutoCreateRef.
To implement the AutoCreateRefTerm, the CallFunction appears to spawn two additional nodes in its ExpandNode - a UK2Node_TemporaryVariable, and a UK2Node_PureAssignmentStatement. The temporary variable inherits the pin type and default object of the CallFunction node, in this case here the pin type is a Class of UObject base, and the default object is set to AActor. The variable is then piped through the PureAssignStatement into the CallFunction node’s ObjectClass input pin. At this step PinConnectionListChanged is called on the input pin, which in turn calls ResetPinToAutoGeneratedDefaultValue, which in turn calls PinDefaultValueChanged on the CallFunction node. It queries the PureAssignStatement for its output type, which is UObject class, and then flips the return value type from AActor to UObject.
I don’t know what the proper way to fix this would be. Maybe the PureAssignmenStatement needs to conform its output type to the input type?
As a workaround we’ve for now removed the AutoCreateRefTerm and instead take the ObjectClass by value.
Ciao, Daniel!
[Attachment Removed]