How to parse arguments to a function added to FOnButtonClickedEvent?

Heya.

This past month I’ve really gotten into Unreal Engine 5.2 and nothing has really stumped me so far, except this issue I’ve been trying to fix.

So for each item in an array I had, I wanted to create a button and have each specific button when pressed do essentially the same code, but use the specific corresponding item for it’s execution.
It should be easy enough to do with a map and all, I just can’t figure out a way to get the specific button which is being pressed and calling the function. I figured I could just parse the button as an argument to the function, but that turned out harder than I thought it’d be.

I’ve tried some different things including using lambdas, making my own custom delegates, etc. but I still can’t seem to find a way to add a way to parse arguments to a function bound to an FOnButtonClickedEvent.

Ideally it would look something like this:

for(Foo item : items){
UButton* Button = NewObject<UButton>(this);
Button->OnClicked.AddDynamic(this, &AClass::OnButtonClick);
}

void AClass::OnButtonClick(UButton* Button){
// Logic using specified button here.
}

However, that obviously doesn’t work.

I instead tried doing it with a lambda, but since FOnButtonClickEvent doesn’t have a BindLambda function, I thought of making my own delegate with something like.

DECLARE_DELEGATE_OneParam(FButtonClickedDelegate, UButton*);
for(Foo item : items){
UButton* Button = NewObject<UButton>(this);
FButtonClickedDelegate ButtonClickedDelegate;
ButtonClickedDelegate.BindUObject(this, &AClass::OnButtonClick);
Button->OnClicked.Add(ButtonClickedDelegate);
}

void AClass::OnButtonClick(UButton* Button){
// Logic using specified button here.
}

However, I can’t find a way to convert my custom delegate to a TScriptDelegate.

I was hoping maybe this would work:

TScriptDelegate ButtonClickedDelegate;
ButtonClickedDelegate.BindUFunction(this, FName("OnButtonClick"));
Button->OnClicked.Add(ButtonClickedDelegate);

However it just crashes unreal as I’d expected. I’m not really sure how I’d get this to work even after searching around for a few hours.

Any and all help would be great. Thank you in advance!

I am not completely sure on the names of things for this, but the logic should be applicable as all you are looking for is getting the appropriate index.

could you maybe just hold the buttons in a TArray<Buttons> ButtonList as TArray can get us indexes without jumping through to many steps. then when a Click event is detected walk through the TArray by index

int32 ii = 0;
for( ; ii < ButtonList.Num(); ii++)
{
    if(ButtonList[ii].IsPressed()){
       break;
    }
}

then take this index and look at the other list of items to match it up, and call the function you need.
could something this work?

That too, works.

What I ended up doing instead though, was make an extension of the button. Then a delegate for said button. In the constructor for said button, I added ‘BindLambda’ to the delegate, which uses ‘AddDynamic’ on the button. Since ‘AddDynamic’ is called from the button extension itself, the function has to be from the same class and I can simply use the ‘this’ keyword to get the handle to my button and execute the logic from the button there.

Then, when the button was added as a child, I then made sure to call said delegate.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.