Sunday, 12 August 2018

Godot - A Complete Guide To Control Nodes - Part 1

This is potentially my most ambitious video yet, so hear me out. If you've ever been confused about Control nodes, hopefully this will even things out a little. I'm going to explain Control nodes in as much excruciating detail as I possibly can.

Basically, Control nodes are super useful for all things that are to do with GUI, so things like menus, HUDs, etc.

So, let's start with the base node, just named "Control", and let's talk about how it's different from the much more straight-forward Node2D.

Node2Ds have a category called "Transform" which holds all of the data for where the node is positioned, how it's rotated and how it's scaled. Pretty simple stuff.

Controls however have a category called "Rect" which deals with all of this, and it's a little bit more convoluted. They do have a position property, a rotation and a scale property, but they also have size properties, pivot offset and clip content.

That's because whereas a Node2D is effectively a marker for drawing 2D graphics, a Control node is an organizational thing for UI elements, so it's actually a box. A Node2D behaves like a point with some Transform values, whereas a Control node is a little rectangle with stuff in it.

It's also worth mentioning that you can't position Control nodes at fractional positions, they'll automatically snap to the nearest pixel. I don't know why this is, but that's the way it is, so I guess deal with it.

Now for the really scary stuff and the thing that prompted me to even make this video, Anchors and Margins.

Basically, this whole system ensures that no matter the screen size, GUI elements will always be in the correct positions. Anchors do this by "anchoring" a Control node to its parent object. If the Control node is the tree root node, then its parent should be a Viewport.

So basically, under "Anchor" there are four properties - "Left", "Top", "Right", and "Bottom". These each refer to edges of the Control node's Rect, relative to the parent. They all take in values from 0 to 1, which represent what percentage along the parent rect size to put each edge.

This is relative to the top-left corner, so if you wanted your control node to alway stay in the top left, you could put "Left" to 0 and "Top" to 0. This means that the Left and Top edges are both 0% along the screen at all times. If you wanted to make the bottom-right corner extend exactly to the center of the screen, you could make "Right" and "Bottom" both 0.5, which would place the Right and Bottom edges precisely 50% along the screen at all times.

So this is super useful to make UI elements proportional to the screen, other UI elements, etc. So what does Margin do?

Well, Margin is basically offset. If you want to offset your shape by a factor of 100 in the x axis, all you have to do is set the "Left" and "Right" values to 100 and it'll move those edges away from the left-hand side of the screen by that amount. However, a warning: these values are absolute, so that means if you shrink the screen below the offset value your elements will probably disappear off the side. I would hesitate to over-use Margins, since it can undermine the whole purpose of using Anchors in the first place.

You can also use margin to actually change the size of the Control node that you're using. So if you set the Left margin to -100 and the Right margin to 100, it'll move the Left edge 100 pixels closer to the left-hand side and it'll move the Right edge 100 pixels away from the left-hand side. This is probably useful for something.

So that's arguably the scariest bit explained, now onto another fairly scary bit- Grow Directions.

So basically, as the name would suggest this is to do with the direction your Control node is expected to grow. If you set both the Horizontal property to "Begin" - as it is by default - you might notice that when you attempt to adjust the Right Margin, it stops changing in size once the size gets to whatever its minimum size is.

However, if you adjust the Left margin and try to shrink the shape horizontally as much as you can, you'll notice that rather than just deny any new growth it'll start to just move instead.

This is because the Control node is effectively ready to start "growing" from the left-hand side if you set Horizontal to "Begin". Think in terms of a Label that's holding a line of text. If you start typing, it should expand away from the left-hand side.

I'll be honest here I'm not sure I entirely understand this bit but it doesn't seem essential so I guess my advice to you is just leave this to "Begin" because otherwise demons and evil spirits will haunt you until either you die or you stop worrying about Grow Directions.

Now for something which is awesome but not as terrifying as the previous stuff, the Focus section!

This is to do with stuff like if you press the tab key, or you want to use the keyboard or a gamepad to navigate menus, stuff like that. If you don't want to deal with this then Godot does actually automatically figure out some of this stuff, but it's not perfect and it frequently gets a bit buggy and confusing.

This category is designed to allow you to manually set which button or node to focus if Godot's messing up or you want to move to somewhere that Godot can't really predict. It's super easy, basically if you select a Button you'll get some "Neighbour" properties named "Neighbour Left", "Neighbour Top", etc.

You can set these properties to point to a node that you want to focus on when the player presses the associated direction on either a gamepad, arrow keys, etc. The Next and Preivous ones work in a similar way, if you haven't explicitly defined any Neighbours but you just want a one-dimensional list of buttons to cycle through for example when the player presses the Tab key, then you can set Next to whatever you want to come next if the player has got that button focused but wants to focus another node.

It's super simple, but a super intuitive way to setup keyboard controls for menu systems.

As for the mouse bit, this describes how the given Control node handles the mouse cursor interacting with it. Imagine that you have two buttons on top of each other, so that one is completely blocking the other. Normally, these would both have the mouse filter set to "Stop" which means that if it receives a mouse event, it'll "block" any item below it from actually receiving that event.

However, if you set the button on top's mouse filter to "Ignore", it'll completely ignore the mouse and you'll be able to click on the button below. This might be useful if you want to hide a button from being interacted with temporarily and for whatever reason setting visibility isn't suitable at that time.

Also, you can set the "Default Cursor" that appears when the user is hovering over the button. It's super easy to use but basically you get a big list of potential options which the cursor will turn into when the button is moused over.

Now for the Size Flags, which I've only ever used with respect to BoxContainers or GridContainers so I guess I'll carry on that traditionand only even teach it with respect to Containers.

From what I can tell, it's a little bit buggy and unpredictable but the important things to note are that Fill makes it take up as much room as possible, but sometimes you need to enable Expand too and I don't know why. Sometimes when you enable Expand once, then disable it, then disable Fill, then re-enable Fill it'll also Expand the node to fill up as much space as it can, for some reason.

You can also use Shrink Center which will sometimes center the nodes in the BoxContainer or GridContainer and keep them at their minimum size, but only if they're really feeling like it. If they're having an off day, then they won't.

This explanation sucked but just press them randomly until you get what you want, they're not that important to understand I guess. If you have a better understanding of these, then please let me know.

As for Styles, again, if you have a good understanding or usecase of these then be my guest but custom styles seem remarkably pointless and difficult to use compared to making panels, buttons etc manually in a sprite editor.

So I guess I've explained the essential components of Control nodes, now I'll get into some more specific instances of Control Nodes, starting from the top, which would be the Popup nodes. Thanks for watching and stay tuned for that in Part 2 of this series that apparently I'm doing now. Goodbye!

No comments :

Post a Comment