GUI 外观定制

Oh, beautiful GUI!

This tutorial is about advanced skinning of a user interface. Most games generally don't need this, as they end up just relying on Label, TextureRect, TextureButton and TextureProgress.

However, many types of games often need complex user interfaces, like MMOs, traditional RPGs, Simulators, Strategy, etc. These kinds of interface are also common in some games that include editors to create content, or interfaces for network connectivity.

Godot's user interface uses these kinds of control with the default theme, but they can be skinned to resemble pretty much any kind of user interface.

主题

The GUI is skinned through the Theme resource. Theme contains all the information required to change the entire visual styling of all controls. Theme options are named, so it's not obvious which name changes what (especially from code), but several tools are provided. The ultimate place to look at what each theme option is for each control, which will always be more up to date than any documentation, is the file scene/resources/default_theme/default_theme.cpp. The rest of this document will explain the different tools used to customize the theme.

A Theme can be applied to any control in the scene. As a result, all children and grand-children controls will use that same theme, too (unless another theme is specified further down the tree). If a value is not found in a theme, it will be searched in themes higher up in the hierarchy, towards the root. If nothing was found, the default theme is used. This system allows for flexible overriding of themes in complex user interfaces.

注意

Don't use the custom theme option in the Project Settings, as there are known bugs with theme propagation. Instead, apply your theme to the root Control node's Theme property. It will propagate to instanced scenes automatically. To get correct theming in the editor for instanced scenes, you can apply the theme resource to the instanced scene's root node as well.

主题选项

一个主题中的每种选项可以是:

  • 整数常量: 一个数值常量。通用用于定义组件之间的间距和对齐相关设置。
  • 颜色:单一颜色,具不具备透明度皆可。颜色通常应用于字体和图标。
  • A Texture: A single image. Textures are not often used, but when they are, they represent handles to pick or icons in a complex control (such as a file dialog).
  • 字体: 每个使用文本的控件都可以设置字体用于绘制字符串。
  • 风格箱: 风格箱是一种资源, 用以定义如何绘制不同大小的面板 (之后见更多信息)。

Every option is associated with:

  • 名称 (选项的名称)
  • 控件 (控件的名称)

示例用法:

var theme = Theme.new()
theme.set_color("font_color", "Label", Color.red)

var label = Label.new()
label.theme = theme
var theme = new Theme();
theme.SetColor("fontColor", "Label", new Color(1.0f, 0.0f, 0.0f));

var label = new Label();
label.Theme = theme;

In the example above, a new theme is created. The "font_color" option is changed and then applied to a label. Therefore, the label's text (and all children and grandchildren labels) will be red.

It is possible to override those options without using the theme directly, and only for a specific control, by using the override API in Control.add_color_override():

var label = Label.new()
label.add_color_override("font_color", Color.red)
var label = new Label();
label.AddColorOverride("fontColor", new Color(1.0f, 0.0f, 0.0f));

In the inline help of Godot (in the Script tab), you can check which theme options are overridable, or check the Control class reference.

自定义控件

如果只需要外观定制少数几个控件, 通常没有必要创建一个新主题。控件提供其主题选项作为特殊类型的属性(在检查面板上)。一旦勾选, 覆写就会生效:

../../_images/themecheck.png

As can be seen in the image above, theme options have little check boxes. If checked, they can be used to override the value of the theme just for that control.

创建主题

The simplest way to create a theme is to edit a theme resource. Create a Theme from the resource menu; the editor will appear immediately. After that, save it (for example, with the name mytheme.theme):

../../_images/sb2.png

这将创建一个空主题, 之后可以将其加载并分配给控件。

示例:指定一个按钮的主题

Download these assets (skin_assets.zip) and add them to your project. Open the theme editor, click on "Edit Theme" and select "Add Class Items":

../../_images/themeci.png

然后将出现一个菜单, 提示要创建的控件类型。选择 "Button":

../../_images/themeci2.png

所有按钮主题选项都将立刻显示在属性面板中, 可以在其中进行编辑:

../../_images/themeci3.png

From Styles, open the "Normal" drop-down menu next to where it probably says "null" and create a "New StyleBoxTexture", then edit it. A texture stylebox contains a texture and the size of the margins that will not stretch when the texture is stretched. This is called nine-patch or "3x3" stretching:

../../_images/sb1.png

重复上述步骤并添加其他资源。示例文件中没有提供“Hover”或“Disabled”的图像, 因此使用与“Normal”状态相同的 stylebox。将提供的字体设置为按钮字体, 并将字体颜色更改为黑色。很快地, 您的按钮将看起来不同了,并且变得复古:

../../_images/sb2.png

Save this theme to the .theme file. Go to the 2D editor and create a few buttons:

../../_images/skinbuttons1.png

Now, go to the root node of the scene and locate the "theme" property, replace it with the theme that was just created. It should look like this:

../../_images/skinbuttons2.png

恭喜咯!您已经创建了一个可反复使用的 GUI 主题!