Issues with setting up Delegate input for a custom K2 Node

Hello,

I’m having trouble setting up my custom K2 Node correctly and it seems like I might be missing something extremely obvious. In the node’s header, I have a function that’s supposed to provide a signature:

public:

	UFUNCTION()
	void Callback (int32 Parameter) {}

Then in that node’s AllocateDefaultPins() I have this passage:

UFunction* FunctionCheck = FindFunction("Callback");
if(FunctionCheck)
{
	UE_LOG(K2Test, Log, TEXT("this UFunction has %d params"), FunctionCheck->NumParms)
	CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Delegate, FunctionCheck, IN_CALLBACK);
}

FindFunction() seems to be capturing the the function correctly (e.g. the debug message correctly reports on the number of params). However, when I try to drag a new custom event from the node in the blueprint, I get an event without parameters. Trying to generate a dispatcher also results in one that doesn’t seem to have the correct signature. Conversely, the node’s input seems to be accepting any event I throw at it and the blueprint still compiles.

I would expect the generated event to look like the “ExpectedResult” (which I created manually just to illustrate).

For the record, the node doesn’t do anything yet, i.e. ExpandNode() looks like this:

::ExpandNode(FKismetCompilerContext& CompilerContext, UEdGraph* SourceGraph)
{
	Super::ExpandNode(CompilerContext, SourceGraph);
	
	BreakAllNodeLinks();
}

Engine version is 5.4.4

While I didn’t manage to solve this issue, I’ve made some progress that makes me think this might be an issue with the engine itself. I’ve created a wrapper USTRUCT with a dynamic delegate inside. I was originally using this delegate in my various BlueprintCallable functions and it worked fine there. I’ve modified the custom node to take this new struct as an input, as opposed to taking a delegate directly. Here’s the result in Blueprint:

The delegate pin in the Make node is acting as expected. But when I “split struct pins” of the main node’s input, the delegate pin that gets generated automatically is treated differently. Intuitively, this should be the exact same pin, because I’m filling out the exact same struct.

Have you already been in UK2Node_AddDelegate::AllocateDefaultPins? :roll_eyes:

No, I haven’t, so thanks for a useful hint.

Now, in the interest of the solution being accessible and searchable, the issue here was that the UEdGraphSchema_K2 header sends you in the wrong direction and implies you need to pass UFUnction as a parameter of CreatePin(). This is not the case. Instead, you need to call a version of CreatePin() that doesn’t take a SubCategoryObject at all, and then use a utility function from FMemberReference to fill out pin data manually. Here’s the code that did the trick in my case:

FCreatePinParams PinParams;
PinParams.bIsConst = true;
PinParams.bIsReference = true;
UFunction* Function = FindFunction("Signature");
if(Function)
{
	NewPin = CreatePin(EGPD_Input, UEdGraphSchema_K2::PC_Delegate, IN_CALLBACK, PinParams);
	FMemberReference::FillSimpleMemberReference<UFunction>(Function, NewPin->PinType.PinSubCategoryMemberReference);
}