UMG buttons and delegates

Hi! I am binding function to my umg buttons in a loop:


for (int32 s = 0; s < this->prevFace.Num(); s++)
{
	this->prevFace[s]->OnClicked.AddDynamic(this, &UCharacterCreationScreen::PrevFaceClick);
	this->nextFace[s]->OnClicked.AddDynamic(this, &UCharacterCreationScreen::NextFaceClick);
}

But I also want to pass int32 parameter along with it, which is not possible with dynamic delegates. I was reading the docs for a few hours, but can not figure solution out.

Theoretically, I should declare


DECLARE_DELEGATE_OneParam(FIntDelegate, int32);

somewhere, and somehow tie it to my


this->prevFace[s]->OnClicked

instead of dynamic delegate? Or I am on the wrong track?

To my knowledge you cannot bind a regular (non-dynamic) delegate to a dynamic delegate. However you can do the inverse with a little bit of additional work.

If I’m not mistaken, the underlying delegates used by slate are non-dynamic. So I’d suggest you try to access and bind to those directly instead of the dynamic OnClicked version.

Something like this (pseudo code, see edit below)


this->nextFace[s]->TheSlateWidget->TheNonDynamicOnClickedDelegate.AddUObject(this, &UCharacterCreationScreen::OnClicked, TheInt32);

Now if you still want a dynamic (multicast) delegate exposed to the editor you could do that from your OnClicked(int32) function.

Edit:
I have the engine source in front of me now. In order to get access to UButton::MyButton you’ll need to subclass UButton as its membervariable TSharedPtr MyButton is protected. Then you can simply change the delegate SButton::OnClicked by calling MyButton->SetOnClicked(TheNewDelegate); where TheNewDelegate is a regular delegate without parameters and an FReply return type. For example


FOnClicked TheNewDelegate = FOnClicked::CreateUObject(this, &UCharacterCreationScreen::OnClicked, TheInt32);

FReply UCharacterCreationScreen::OnClicked(int32 Argument)
{
	//...
}

Thanks a lot for getting back! I’ll figure everything out now, based on you reply.

No matter what I do, I can not bind the event:


FOnClicked TheNewDelegate = FOnClicked::CreateUObject(this, &UCharacterCreationScreen::PrevFaceClick, s);

I am running it from inside UActorComponent class, also tried to run directly from inside UButton subclass, also like this:


FOnClicked TheNewDelegate = FOnClicked::CreateUObject<UCharacterCreationScreen, int32>(this, &UCharacterCreationScreen::PrevFaceClick, s);

Any idea, where I’ve got it wrong?

9cb97fbffad93f01ebddc74a87da976b2e9408b1.jpeg

The whole error message would have helped me figure out what exactly is wrong but I think I recognized the problem from the visible bits.
The function bound to the delegate MUST have a return value type of FReply. In your case it looks like the function return type of PrevFaceClick is void. This is an obvious mismatch and therefore the compiler complains. See the last error message "note: while trying to match the argument list ‘(UCharacterCreationScreen const, void (__cdecl UCharacterCreationScreen::)(int32), int32)’ from your screenshot.
So all you need to do is change the return type of your function from void to FReply (and actually return some FReply from its implementation).

I see! For some reason it totally did nor occur to me, that I need also to check return type. It all seems obvious now.