How do you call the click event on a specific button in an array of buttons in UMG?

I’m working on a menu that is both mouse and keyboard driven. I have it setup so that you can click on options (although only one will currently do anything) or you can use the up and down arrows to move a cursor. The idea is when they hit enter it will be as if they clicked the button next to the cursor. I know which button has been selected. I just don’t know how to call the event. If I start typing click all I get is “Get Click Method”. I thought that might help, but its actually an enum that describes how they clicked. Not actually what I’m looking for. In Javascript I could say buttons[selected].click();

Any suggestions for activating a specific button?

Not sure if this is what you are after, this is done out of widget in seperate bp

Capture.JPG

Hello,
To have your click event “On Clicked”, select the button in the “My Blueprint” tab and check the “Details” tab : down of Details : Events : “on clicked” and a green bar with a +. Click the green bar to have the event in event graph.

If you have a lot of buttons you may prefer use a second widget with a button, an index, a custom event / function with index as input if you need to “get” an array value and the “On Click” event. A bit more complicated, you need a reference to the first widget too, set on construct, to have access to the array, but usefull as you can create an array of buttons in an uniform grid panel (like for an inventory) with it.

I already have the event and it works when I click on it with a mouse. I’m trying to trigger that event by selecting it with the keyboard and hitting enter to trigger it as if the button was clicked.
I’m not home right now so I can’t try this, but I wonder if I can make an array of events (created similarly to the way I made the array of buttons) and call the correct event. I’m trying to minimize hard coding though because as the menu expands its going to get harder to keep it updated.

I’m building a pretty menu heavy game and need both controller & mouse/keyboard support.

To do this, I’m manually managing & tracking what button is active. Basically if every button is in a scroll box or vertical box, I’m keeping track of an INT for which has focus. When a key press event is detected (i.e.: Gamepad A or Enter) I’m calling an event in a blueprint interface on the in the slot corresponding to the INT. Each button has an interface event I’m calling “simulated button press”, which executes the same path as the actual button press.

On arrow/L-Stick up & down, I’m incrementing & decrementing the int, as long as it’s within the bounds of the child count of the parent box that holds all the buttons. On each change of that INT, I’m also updating the children of the box to set their various focused attributes (unhide an arrow, set the style of the button).

This setup is really extensible and reusable, since the only data that the player is changing is the currently focused INT, and the it can go is based on a child count of the parent.

Somewhat annoyingly, I also need to flag “can have focus” to OFF on everything, otherwise the existing shoddy tab-style focus system can get in the way, and eat your non-mouse click inputs.

Here’s the list in the UMG editor (all values are defined on user widgets, so they show as NULL in editor). Also I’ve attached where I’m passing along focus to the focused child, and the basic loop I’m doing to update focus whenever an input occurs that changes focus.

That’s exactly what I’m doing. I have a selected index and inc/dec in the keypressed event handler.

This is what I have. The up and down already work. The if LKey==“Enter” is the part where I’m not sure what to do. What does your keyPressPassThrough do?

I’m thinking since each button has (or will have an event anyway) I can probably just add those events to an array and hopefully call that.
I was HOPING I could save this to a variable, but no you aren’t allowed to make variable events.
Well that’s ok I’ll just use the array constructor to call the event.
NOPE you can’t do that either. There is no possible way to execute the event that I can see.

Let me back up & describe my hierarchy for a moment. The prior example are from my options screen, which doesn’t pass through “enter/gamepad A” events, since the screen just has a “confirm/decline” button that sets everything. I’m attaching a new image from our inventory screen, which is structured thus:

  • > MasterJournal (handles all input, uses a widget switcher to change panels)
    — > InventoryPanel (houses the inventory scroll box, a list of all inventory items - my screenshot is from this widget)
    ------ > Inventory Item (a unique UMG widget for each item. Basically a button with a couple images)
    — > CraftingPanel
    — > EquipmentPanel

When the MasterJournal fires the Key Down Event, the children (in this case, InventoryPanel) have the the blueprint interface implemented, so they can receive the event (in this case, Key Down Event, which is in BPI_UI_Interface).

The buttons themselves just have a Custom Event (Simulate Click) which I fire by casting to the button class (UIW_InventoryItem). Basically I’m always sending a waterfall of events through the MasterJournal, and directing the events based on which is focused.

Incidentally, since you have an index, you don’t need to bother with the array of widgets. If you just use “Get Child At” on the widget that houses your buttons, it give you whatever widget is there. If you cast to that and it’s the wrong type, the cast fails and nothing bad happens. Same with a blueprint interface. If you try to fire an event on a widget and it doesn’t have the interface implemented, or the associated event, nothing bad happens.

Based on your images, I would suggest (mostly for reasons of extensibility & good housekeeping) that rather than adding a bunch of buttons to your screen, that you make a bunch of widget types that you can just embed.

In the case of my options screen, there are a bunch of generalized widgets I’m using.

UIW_OptionsScreen is the base screen, has the scroll box, and has a bunch of the other widgets added as “user widgets”.
UIW_Options_List, UIW_Options_Button, UIW_Options_Toggle, and UIW_Options_ toggle are all just a single widget designed to perform one of those actions. So If I want to add more toggles (Extreme Gore!, Big Head Mode!) I don’t need to change any base data, I just need to add another widget, give it the name, and bind it to whatever I want it to set.

Also, fwiw my main menu is a bit simpler, and does just have buttons. I’m attaching an image of the “On Key Down” handler, and what I’m doing with it via the “simulate key press” custom event.

I guess what I should do is make a function to handle ALL the options and have all the buttons pass their respective indices.
It looks like that’s what you did.
How disappointing that it doesn’t work the way I wanted it to.

It works. I guess if the individual options get too complex, I can put the individual functions in separate functions and call those from the main button pressed function.

Wow - I have the exact same problem. I just want to fire a button’s OnClicked event in Blueprints code so that I can write code that is more generic and reusable (and requires less effort wasted on tedious maintenance).

The purpose is so I can write generic Blueprints code to handle gamepad interactions with vertical boxes that contain buttons.

If I could just fire a button’s OnClicked event, it would be so much more flexible because I wouldn’t have to hardcode in my Blueprints code which menu index points to which function. Instead, my Blueprints code would just get the corresponding button from the vertical box based on its index…

That way if I ever want to change UMG buttons (or their OnClicked event callbacks) in WYSIWYG, then my Blueprints code would automatically work with the change - ie I would not need to also modify my Blueprints code.

I love UE4 and I love UMG, but this is a design mistake. You should be able to trigger a Button’s OnClicked Event in Blueprints code. It’s such a basic thing that I am shocked it’s missing. I hope they add it soon!

1 Like

How about this: wrap the button in your own custom widget, create an “OnClick” event dispatcher and automatically call that event inside of your custom widget when the button is clicked.
It only requires some small setup to start but after that it can function just like a button except you can manually call OnClick if you want.

Here’s a step by step just to be clear:

First create a new widget. For this example I’m creating a new one but you can also just add this to your existing button widget if you already have one.

I’m going to make it act mostly like a regular button for this example but it can contain whatever you want.
(1, 2, and 3) Add a button, add a named slot to the button and call it “Content” (or something similar).
(4) Select the button and Ctrl-Shift-Click to make the button fill the canvas. EDIT: Or rather just make the button the root widget.

(1) Select the button, scroll down to events, and click the “+” next to “OnClicked”.
(2) On the left under “Event Dispatchers” click the plus to add a dispatcher and name it “OnClick” (or something similar)
(3) Attach a call to the newly created dispatcher to the button’s OnClicked event.

You can now use the widget exactly like you would a regular button.
(1, 2) You can find it under “User Created” in the palette.
(3) Add the OnClick even just like you would for a regular button and add whatever code you want.

Now you can manually trigger the OnClick event any you want
4.jpg

[HR][/HR]

If you don’t want to do that you could also wrap all button actions in functions. It still requires work for each button but your graph will be more manageable.


Then instead your switch will look like this:

2 Likes

It simple thing than complicated blueprint.
Menu -> buttons
Button -> event action
Button.click -> execute event action
Button.mouseover -> select the button as current button
Key press [e] -> curent button.event action.
This run ok and tested.
The concept , each button has an event action , when click it execute it.
The issue is execute button event action from keyboard.
You can name button by assign an id with it. When the mouse is over or use direct key to change the id then execute it as curent.

Hello, I’m having the same problem…
Is basically the answer to the query… that “no you can’t trigger the On Click events manually” so if you wanna have something flexible. you basically just manipulate the button styles and simulate a click… and in this way you have to define button styles in a different place that just ON the button…

any news on this would be sweet.

This popped up for me as well.

I want to have an alternative method of clicking on buttons using the number keys on the keyboard. That means I have to create an array of all buttons in a menu and call onclick on one of them depending on what menu is open and what number key was pressed.

No, I don’t wrap my buttons in user widgets, because I can’t get those to 100% act like the default buttons do right now.

So, this still is not possible in 2020?

I have a workaround for this. Currently working on it now, and i was doing a little search.
I’ll post it here as its done :slight_smile:

Make a widget child, call it “childWidget_Buttons”

Setup this inside your child widget

Then you make this inside the widget thats going to have the button

This allows you to store the buttons to an array, call simulate click, etc…

Use public variables and edit it like (Inside the child widget blueprint) this if you want text on the button etc other important options, and add public variables to what you want to edit on the child button, once added to the parent widget!