Saturday, 25 August 2018

Godot - A Complete Guide To Control Nodes - Buttons

Amazing! We're back, and do I have a tutorial for you. I suspect this one is gonna be pretty popular because I mean- pretty much everyone wants to know about Buttons, so let's go!

I'm sure that pretty much anybody watching this video will use Button nodes at some point in their gamedev experience with Godot. If they don't, then that's strange but they probably should.

So let's move onto the big old Node tree and take a look at what's going on- you might notice that all of the Button nodes are actually children of this unselectable "BaseButton" thing. This is exactly what it sounds like, it's an uninstanceable class which aggregates all of the core behaviour for all of the button Nodes in the engine.

Looking at the documentation, that includes things like some methods like _pressed(), _toggled(), is_hovered(), etc. These are things which every button should have, and you will be able to call on any button. It's pretty easy to figure out what each of these do, so I won't go into much detail on them.

Also, every Button node you encounter will have a few SUPER helpful signals- button_down(), button_up(), pressed() and toggled().

Again- these are very self-explanatory, but they're super helpful. Basically, I would usually put all of the button-press logic into a pressed() callback, and then you can set the "action_mode" to determine whether to emit that signal when the button is pressed down, or when it's released. This just gives you a bit more freedom to make changes later on should you change your mind about the way the button works, so I'd recommend it.

So anyway, let's create a proper Button node and investigate some of this stuff. First, let's take a look at the inspector category known as "BaseButton". The first few properties here are pretty easy to understand, there's "Disabled" which when activated will make the button not clickable and in the case of a normal Button node, it'll also make it greyed out.

There's "Toggle Mode" which basically determines whether or not it's a button that you press once to enable, and press again to disable. Kind of like a check-box kind of thing, if you want that then enable the "toggle mode" property but if not then just ignore it and you're good.

"Pressed" is pretty self-explanatory, but you're probably not gonna be adjusting this one from the Node inspector. Chances are, you'll be using that one in some if statements- like if(button.pressed): do a thing.

I briefly mentioned "action mode" earlier, and it basically determines whether or not the "pressed" action happens when the mouse is pressed down on the button, or whether the mouse is released from the button after pressing it down. This is set to "button release" by default, and for most UI or menus I generally leave it that way. However, you could change it if you feel like it.

"Focus Mode" determines whether or not this button is allowed to grab focus, and if so- how. By default, it's set to "All" which means that you can use the arrow keys or the mouse to select it, much like how we did in the first video in this series when I was demonstrating the "neighbours" stuff under the "Focus" category.

"Click" means that you can't use the arrow keys to select this button and you have to click it manually with the mouse, and "None" means that you just can't focus this button.

Now this one is pretty cool and I'm just waiting for an excuse to use it, but you can set a "Shortcut"- this means a keypress that will automatically press that button. So you could make a new shortcut, create a new InputEventKey and you can look up the scancode to the button of your choosing. This makes keyboard shortcuts SUPER easy to work with.

Also, you can set the "group" of the button. You can't really set this one in the inspector, but in a script you can create a new ButtonGroup object which you can then assign to multiple buttons. This means that at any given time, only one of the buttons in the group can be pressed. It's kind of like radio button selections on a webpage.

So now onto the specifics of this "Button" node, since the things we just covered are applicable to any button- they're all members of the "BaseButton" class.

The first property to notice is "Text", which is pretty easy to deal with, if you want your button to say something then you can type it in here and it'll show up on the button.

There are a few other properties that relate to this text like "Clip Text", which will stop the text from leaving the bounds of the button and "Align" which will designate how the text is aligned.

"Icon" allows you to set a nice little image to appear on the left hand side of the button, or if you don't have any text, you can just shrink the button to make it appear in the middle.

Also, you can set the "Flat" property which just changes the style of the button a little bit, by making it not show up by default.

So, now onto some of these simple button derivatives- first of all the CheckBox. This one is literally just a checkbox and is generally used in combination with some text next to it and some other context.

Next, there's the CheckButton. This is functionally identical to a checkbox, but instead of a literal checkbox it actually has a little switch which you can set as "on" or "off".

Now there's the "ColorPickerButton" which is pretty useful. It basically allows you to select a colour using preset Godot UI stuff just by creating the node. From there, all you have to do is connect the "color_changed" signal, and access the "color" property that it has. This makes things like character selection super easy- if you don't mind Godot's built-in UI too much.

Next, there's the "MenuButton". This is kind of like a dropdown menu type thing, if you click "Scene" at the top it'll produce a bunch of options- at the moment, we haven't really set this up. However, when it clicks it creates a PopupMenu and you can see my last video to get a sense for how to make that work. You can use the "get_popup()" function on it to get the PopupMenu node for all your GDScript customization needs.

There's also the super useful "OptionButton", which is again a node that mostly requires customization via script files. You can add items and link the "item_selected" signal to a script of your choosing in order to determine which one got selected. It's not super complicated to use, but yeah- just play around with it.

Now for the one that I use probably the most(excluding the TextureButton), the ToolButton. It's literally identical to the normal Button node, except it automatically sets itself to flat. That's it.

Now there are only two buttons left, and they're both pretty useful. The first one is called a LinkButton and it's just like when you have a hyperlink on a webpage. This LinkButton is functionally exactly the same as any other button with the signals, etc- it just presents itself as a hyperlink.

Then the last one that I definitely use the most, the TextureButton. Again, it's functionally identical as a button node but it takes in several textures instead of relying on Godot's own user interface style stuff.

It has an "Expand" property which basically determines whether the texture should expand to the full extents of the button size. This is in combination with the "stretch mode", which determines how it expands- whether it tiles, whether it stretches, or whether it keeps itself centered and a bunch more options. Generally speaking, I leave this disabled since I make my textures in something like Aseprite and only load them in via the TextureButton to be displayed at the size I designated in my sprite editor.

But the point is yeah, this is a pretty useful node. You can even set a click mask if you don't want the entire Rect to be able to be clickable. Just load in a bitmap with white as the clickable area and black as the non-clickable area, and then Godot will automatically do the rest. It's super useful for making curved buttons, or buttons that are smaller than your TextureButton Rect for whatever reason.

And there you have it, that's pretty much it for Buttons. As always if you have any further questions then feel free to leave a comment, or join my Discord and ask me there- I'm usually quite happy to be distracted from whatever I'm doing so feel free to make use of that. Anyway, thanks for watching and stay tuned for more tutorial videos because apparently you guys LOVE them, I'm getting so many subscribers it's literally the best thing that's ever happened to me. Anyway, I guess next time I'll do Containers- which is a slightly bigger and significantly more scary topic. I might have to segment that one into two or more videos, come to think of it but whatever. Just enjoy what I've done so far!

No comments :

Post a comment