Hey guys, this is the Modular Menu System support thread.
Just as a short introduction, to see what the menu system is capable of, have a look at this video:
If you have purchased this asset from the UE4 Marketplace, please feel free to ask all your technical questions here. Alternatively you can also [EMAIL=“firstname.lastname@example.org”]write us an email. We will get back to your support requests here or via email as soon as possible!
[NOTE]Moved this over here from the release thread![/NOTE]
I’ve gone over the PDF and gotten a menu showing up (I’m slowly replacing my old menu setup), but I have one issue: the guide doesn’t detail setting up callbacks. I have to admit I haven’t done this much yet and it’s been quite a while since I did it in raw code in various programming/scripting languages. I’ve been spoiled with blueprints, haha! Any chance you can write up a quick button callback tutorial? I’ve got a sub-classed event handler going (it’s empty) but not sure where to go from there. I’ve also made and set variables for 2 buttons (resume and quit) in my menu blueprint (where I setup the event handler, menu, create elements like buttons and such). Might be privy to update the PDF guide with that info as well, for others that might be as clueless as myself
Just ran into a bug… When I bring up my pause menu with escape, then hide the menu/un-pause, then pause/show menu again, the menu re-sizes to fill the screen.
So I’ve been struggling with this for a few hours now. I am assuming the button stuff hasn’t been fully implemented? I’m just not seeing how to get button states. You can check for a lot of other element states (such as checkboxes and so on), but not for one of the most widely used elements in any UI: buttons! I see there is an enum for buttons states, but not seeing where it is being set. I’m hoping a bit more ease-of-use is put forward for working with buttons…
Yeah, the button callback wasn’t in the PDF so I had to look at the example project’s event handler that comes along with this.
In your event handler event graph, right click and type in Button Callback, and Event Button Callback should be returned. Place this node into your graph. It should have an ID input. This is the ID of the button. You will need to compare the ID input to one of the ID’s you created for your buttons to know which button actually got pressed.
I wish there was a better way to do this though as it is doing a string/name compare and if you have a lot of buttons, there will be a lot of Branch nodes. Hopefully, in the future, there will be a datatable that contains all of the button id’s and information that can be read from in the button callback so there is no more string comparison.
The reason why you can’t query the state of a button is that there is not really such a state. Well, technically there is a state: either default (not pressed), or pressed. But the latter is only relevant while the user is pressing a button. And we assumed there is no reason to check whether the user is pressing a button at one very moment (which lasts only for some miliseconds). The other elements have constants states – like a checkbox, it is either selected or not selected.
However, the event handler will tell you as soon as a button is being pressed. In your custom event handler class, the one that you have derived from MMS_EventHandler, do the following: Override the function ButtonCallback, this will be called every time a button is being pressed. That function has an input parameter “ID”, which you can compare with those button IDs you have used when you created your buttons. With that information you can implement whatever logic for a button that you like.
Thanks for the feedback, I have added a section on button callbacks to the manual.
I am open for any constructive feedback, and if you think there might be an improvement in how to handle button clicks, I am more than happy to implement it. In this case however I am afraid I don’t really see what you are asking for. You don’t need to add multiple branches, you could also just add a string switch and handle each button ID directly. But maybe I have missunderstood your request. Could you please elaborate a bit on that? Thanks.
I am afraid that’s not possible, because I cannot dynamically create new functions from within BP.
I will think of alternative options here, but for now I hope using a string switch is a suitable way to go
Thanks for the reply and good to see that bug fix will be right around the corner! I did get a method figured out for easily handling buttons, pretty much as you laid out. I think building in a simple function to get a boolean back with button clicked would be nice. Just pass in ID and/or Caption and return true or false. It’s what I did on my end, but I have to put in a timeline with a ~0.1 second length for check delays, otherwise once it’s true, it stays true. Basically, once the button clicked fires, it’s sticking as clicked. I probably did something wrong, it’s a simple blueprint so I can paste a screenshot if my explanation isn’t clear enough.
Went ahead and grabbed screens of how I’m doing things:
As an aside, there are a lot of warnings popping up when exiting the game about menu widgets already being added to the screen. I only add them once, but it seems when showing/hiding that warning gets thrown. Doesn’t seem to effect functionality, just an annoyance when the log pops up after every PIE test, for example.
Two things: First, as a general rule, try to avoid using timelines in your tick functions. Remember that tick is called every single frame, that is, around 30-60 times per second. Thus also your timeline is being called that often per second. This will slow down your game a lot!
And as of your solution, I am not sure whether I fully understand what you are trying to achive. In general, when using callbacks, usually you don’t neet do actively poll the status of an element (e.g. via tick). That is the reason for using event handlers in the first place: React to the event with your logic only and directly when the event occurs.
So, in the case of buttons in MMS: Let’s say you want to quit the application when a button with ID “exitBtn” is being pressed. Now all you need to do is to overwrite the “ButtonCallback” function in your custom event handler, compare the ID import parameter with “exitBtn” and if that is true simply call the QuitGame BP node. That’s it, no need to actively query the state of a button
Yeah… I knew doing the timeline thing was bad practice, it was just a quick and dirty way to reset my reference of the clicked ID to null/none. I check elsewhere against that variable, which sticks to the last button clicked if I don’t reset it.
I have several “controller” blueprints: BP_CTRL_Audio, BP_CTRL_Visual, BP_CTRL_AI, etc., and one of these is BP_CTRL_GUI. In the GUI controller, I previously (before implementing your handy-dandy offering) had a function for checking if a button was pressed. It was generic, I could just pass in a button ID and get a boolean back. I’m having a hard time replicating that with this new setup. Ideally, I’d like to do a “Bind Event” in my GUI controller for the button clicked, but get back a boolean if ID matches. I’m simply unsure how to do this elegantly and efficiently.
I’m thinking I’m just missing the simplicity of getting a boolean result for whether a button was clicked. I’d rather not lay everything out in the event handler- my goal was to just catch events and pass data through. I’ve been burning the candle at both ends the last 2 weeks, as they say… So I’ve been brain-farting a lot, haha…
Anyhow, thanks for the support and speedy responses. I rated MMS 5 stars on the Marketplace and will certainly be suggesting it to others when the topic of menu systems comes up!
Okay, this is really throwing me for a loop now. In the custom event handler, I create an event dispatcher: “ED_ButtonClicked”. On the override for the “Event Button Callback”, I call this. Now in my other blueprint, BP_CTRL_GUI, on BeginPlay I bind that “ED_ButtonClicked” to a custom event, “Event ButtonClicked”. All I’m doing is passing through the ID of the button that was clicked. I then print that to the screen. Well, try to. It simply doesn’t work. If I do all that in the event handler blueprint, it works fine. Here’s screenshots of the simple blueprint layouts:
Okay- my buttons are magically working now. I didn’t change anything, but after closing out my project and taking a break and then coming back… For some crazy (but welcomed) reason, the setup I posted above now works. I’m glad too, as this feels the most elegant and organized. However, is you know of a better way of going about his, please let me know!
Cool deal… Though, my menus all broke now. I’ve spent the last hour re-building things, as reference types and such seemed to have changed? On my end, the node “Create Simple Menu” outputs and “Object”, rather than a simple menu type for example. So I have to cast to simple menu on that end. The structure types for buttons are all invalid in my setup now, so I have to re-create all those. I’ve never had an issue when updating stuff from the marketplace, so I can only imagine I did something wrong. I’ll come back with more info once I get this tackled.