mirror of
https://github.com/godotengine/godot-demo-projects.git
synced 2026-01-06 16:00:08 +01:00
Add a demo on supporting multiple resolutions and aspect ratios
This demo intends to showcase what Godot can do in terms of supporting multiple resolutions and aspect ratios.
This commit is contained in:
94
gui/multiple_resolutions/README.md
Normal file
94
gui/multiple_resolutions/README.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Multiple Resolutions and Aspect Ratios
|
||||
|
||||
**Note:** This demo is intended to showcase what Godot can do in terms of
|
||||
supporting multiple resolutions and aspect ratios. As such, this demo very
|
||||
full-featured but it's also fairly complex to understand.
|
||||
|
||||
If you're in a hurry and want to implement *decent* support for multiple
|
||||
resolutions and aspect ratios in your game, see [Multiple resolutions crash
|
||||
course](#multiple-resolutions-crash-course).
|
||||
|
||||
___
|
||||
|
||||
This project demonstrates how to set up a project to handle screens of multiple
|
||||
resolutions and aspect ratios.
|
||||
|
||||
This demo allows you to adjust the window's base resolution, stretch mode,
|
||||
stretch aspect, and scale factor (internally known as "stretch shrink"). This
|
||||
lets you see what happens when adjusting those properties. Make sure to resize
|
||||
the project window in any direction to see the difference with the various
|
||||
stretch mode and stretch aspect settings.
|
||||
|
||||
The GUI can be made to fit the window or constrained to a specific aspect ratio
|
||||
from a list of common aspect ratios. On ultrawide aspect ratios, this can be
|
||||
used to prevent HUD elements from being too spread apart, which can harm the
|
||||
gameplay experience. For non-essential HUD elements, specific controls can be
|
||||
made to ignore this aspect ratio constraint when it makes sense (e.g. a list of
|
||||
players on the side of the screen).
|
||||
|
||||
Additionally, a GUI margin setting is provided to better handle TVs with an
|
||||
overscan area to prevent GUI elements from being cut off. This can also improve
|
||||
the gameplay experience on large monitors by bringing HUD elements closer to the
|
||||
center of the screen.
|
||||
|
||||
A DynamicFont is also used to ensure font rendering remains crisp at high
|
||||
resolutions, thanks to Godot's built-in support for font oversampling. In other
|
||||
words, the engine will automatically re-rasterize fonts at different resolutions
|
||||
than the base window size when the window is resized (or when the window scale
|
||||
factor is changed).
|
||||
|
||||
Language: GDScript
|
||||
|
||||
Renderer: GLES 2
|
||||
|
||||
## Technical notes
|
||||
|
||||
The demo works with the following project settings:
|
||||
|
||||
- `2d` stretch mode (recommended for most non-pixel art games).
|
||||
- `expand` stretch aspect (allows support for multiple aspect ratios without
|
||||
distortion or black bars).
|
||||
- Using a base window size with a 1:1 aspect ratio (`648×648` in this demo).
|
||||
This prevents GUI elements from automatically shrinking, even in portrait
|
||||
mode.
|
||||
- With this setting, to prevent the GUI from breaking at narrow aspect ratios,
|
||||
the GUI must be designed to work with a 1:1 aspect ratio. This is not
|
||||
feasible in most complex games, so a base window size with a wider aspect
|
||||
ratio (such as 4:3 or 16:10) can be used instead. The wider the aspect
|
||||
ratio, the easier design becomes, but the GUI will automatically become
|
||||
smaller at narrow aspect ratios unless the user overrides its scale with the
|
||||
stretch shrink setting. Many devices such as the Steam Deck and MacBooks
|
||||
feature 16:10 displays, so it's recommended to use a 16:10 resolution or
|
||||
narrower as a base window size to ensure a good gameplay experience out of
|
||||
the box on those devices.
|
||||
- Using a test window size with a 16:9 aspect ratio (`1152×648` in this demo).
|
||||
This way, the project starts in a 16:9 window even if the base window size has
|
||||
a 1:1 aspect ratio.
|
||||
- The test window height matches the width and height of the base window size,
|
||||
so GUI elements are still at the same size.
|
||||
|
||||
## Multiple resolutions crash course
|
||||
|
||||
**Not everything in this demo is critical to all games.** For gamejam projects or mobile games, most of this can be skipped.
|
||||
See the [Common use case scenarios](https://docs.godotengine.org/en/stable/tutorials/rendering/multiple_resolutions.html#common-use-case-scenarios)
|
||||
section in the Multiple resolutions documentation.
|
||||
|
||||
With the simpler setup described in the above documentation, there are a few
|
||||
limitations compared to this demo:
|
||||
|
||||
- The HUD will shrink when the aspect ratio becomes narrower than the base
|
||||
window size. As such, it's recommended to use a base window size with a 16:10
|
||||
aspect ratio to prevent the HUD from shrinking on Steam Deck and MacBooks.
|
||||
- Players will not be able to define a margin, which can be problematic when
|
||||
playing on a TV (as overscan can obstruct some HUD elements). This can be
|
||||
worked around by ensuring the entire HUD always has a small margin around it.
|
||||
This can be done by increasing the Margin properties on all sides on the root
|
||||
Control node by 10-30 pixels or so.
|
||||
|
||||
If you're releasing a full-fledged game on a desktop platform such as Steam,
|
||||
consider implementing full support as this demo suggests. Your players will
|
||||
thank you :slightly_smiling_face:
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
BIN
gui/multiple_resolutions/icon.png
Normal file
BIN
gui/multiple_resolutions/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 684 B |
35
gui/multiple_resolutions/icon.png.import
Normal file
35
gui/multiple_resolutions/icon.png.import
Normal file
@@ -0,0 +1,35 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="StreamTexture"
|
||||
path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://icon.png"
|
||||
dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_mode=0
|
||||
compress/bptc_ldr=0
|
||||
compress/normal_map=0
|
||||
flags/repeat=0
|
||||
flags/filter=true
|
||||
flags/mipmaps=false
|
||||
flags/anisotropic=false
|
||||
flags/srgb=2
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/HDR_as_SRGB=false
|
||||
process/invert_color=false
|
||||
process/normal_map_invert_y=false
|
||||
stream=false
|
||||
size_limit=0
|
||||
detect_3d=true
|
||||
svg/scale=1.0
|
||||
129
gui/multiple_resolutions/main.gd
Normal file
129
gui/multiple_resolutions/main.gd
Normal file
@@ -0,0 +1,129 @@
|
||||
# The root Control node ("Main") and AspectRatioContainer nodes are the most important
|
||||
# pieces of this demo.
|
||||
# Both nodes have their Layout set to Full Rect
|
||||
# (with their rect spread across the whole viewport, and Anchor set to Full Rect).
|
||||
extends Control
|
||||
|
||||
var base_window_size = Vector2(ProjectSettings.get_setting("display/window/size/width"), ProjectSettings.get_setting("display/window/size/height"))
|
||||
|
||||
# These defaults match this demo's project settings. Adjust as needed if adapting this
|
||||
# in your own project.
|
||||
var stretch_mode = SceneTree.STRETCH_MODE_2D
|
||||
var stretch_aspect = SceneTree.STRETCH_ASPECT_EXPAND
|
||||
|
||||
var scale_factor = 1.0
|
||||
var gui_aspect_ratio = -1.0
|
||||
var gui_margin = 0.0
|
||||
|
||||
onready var panel = $Panel
|
||||
onready var arc = $Panel/AspectRatioContainer
|
||||
|
||||
|
||||
func _ready():
|
||||
# The `resized` signal will be emitted when the window size changes, as the root Control node
|
||||
# is resized whenever the window size changes. This is because the root Control node
|
||||
# uses a Full Rect anchor, so its size will always be equal to the window size.
|
||||
# warning-ignore:return_value_discarded
|
||||
connect("resized", self, "_on_resized")
|
||||
update_container()
|
||||
|
||||
|
||||
func update_container():
|
||||
# The code within this function needs to be run twice to work around an issue with containers
|
||||
# having a 1-frame delay with updates.
|
||||
# Otherwise, `panel.rect_size` returns a value of the previous frame, which results in incorrect
|
||||
# sizing of the inner AspectRatioContainer when using the Fit to Window setting.
|
||||
for _i in 2:
|
||||
if is_equal_approx(gui_aspect_ratio, -1.0):
|
||||
# Fit to Window. Tell the AspectRatioContainer to use the same aspect ratio as the window,
|
||||
# making the AspectRatioContainer not have any visible effect.
|
||||
arc.ratio = panel.rect_size.aspect()
|
||||
# Apply GUI margin on the AspectRatioContainer's parent (Panel).
|
||||
# This also makes the GUI margin apply on controls located outside the AspectRatioContainer
|
||||
# (such as the inner side label in this demo).
|
||||
panel.margin_top = gui_margin
|
||||
panel.margin_bottom = -gui_margin
|
||||
else:
|
||||
# Constrained aspect ratio.
|
||||
arc.ratio = min(panel.rect_size.aspect(), gui_aspect_ratio)
|
||||
# Adjust top and bottom margins relative to the aspect ratio when it's constrained.
|
||||
# This ensures that GUI margin settings behave exactly as if the window had the
|
||||
# original aspect ratio size.
|
||||
panel.margin_top = gui_margin / gui_aspect_ratio
|
||||
panel.margin_bottom = -gui_margin / gui_aspect_ratio
|
||||
|
||||
panel.margin_left = gui_margin
|
||||
panel.margin_right = -gui_margin
|
||||
|
||||
|
||||
func _on_gui_aspect_ratio_item_selected(index):
|
||||
match index:
|
||||
0: # Fit to Window
|
||||
gui_aspect_ratio = -1.0
|
||||
1: # 5:4
|
||||
gui_aspect_ratio = 5.0 / 4.0
|
||||
2: # 4:3
|
||||
gui_aspect_ratio = 4.0 / 3.0
|
||||
3: # 3:2
|
||||
gui_aspect_ratio = 3.0 / 2.0
|
||||
4: # 16:10
|
||||
gui_aspect_ratio = 16.0 / 10.0
|
||||
5: # 16:9
|
||||
gui_aspect_ratio = 16.0 / 9.0
|
||||
6: # 21:9
|
||||
gui_aspect_ratio = 21.0 / 9.0
|
||||
|
||||
update_container()
|
||||
|
||||
|
||||
func _on_resized():
|
||||
update_container()
|
||||
|
||||
|
||||
func _on_gui_margin_drag_ended(_value_changed):
|
||||
gui_margin = $"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMargin/HSlider".value
|
||||
$"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMargin/Value".text = str(gui_margin)
|
||||
update_container()
|
||||
|
||||
|
||||
func _on_window_base_size_item_selected(index):
|
||||
match index:
|
||||
0: # 648×648 (1:1)
|
||||
base_window_size = Vector2(648, 648)
|
||||
1: # 640×480 (4:3)
|
||||
base_window_size = Vector2(640, 480)
|
||||
2: # 720×480 (3:2)
|
||||
base_window_size = Vector2(720, 480)
|
||||
3: # 800×600 (4:3)
|
||||
base_window_size = Vector2(800, 600)
|
||||
4: # 1152×648 (16:9)
|
||||
base_window_size = Vector2(1152, 648)
|
||||
5: # 1280×720 (16:9)
|
||||
base_window_size = Vector2(1280, 720)
|
||||
6: # 1280×800 (16:10)
|
||||
base_window_size = Vector2(1280, 800)
|
||||
7: # 1680×720 (21:9)
|
||||
base_window_size = Vector2(1680, 720)
|
||||
|
||||
get_tree().set_screen_stretch(stretch_mode, stretch_aspect, base_window_size, scale_factor)
|
||||
update_container()
|
||||
|
||||
|
||||
func _on_window_stretch_mode_item_selected(index):
|
||||
stretch_mode = index
|
||||
get_tree().set_screen_stretch(stretch_mode, stretch_aspect, base_window_size, scale_factor)
|
||||
|
||||
# Disable irrelevant options when the stretch mode is Disabled.
|
||||
$"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowBaseSize/OptionButton".disabled = stretch_mode == SceneTree.STRETCH_MODE_DISABLED
|
||||
$"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowStretchAspect/OptionButton".disabled = stretch_mode == SceneTree.STRETCH_MODE_DISABLED
|
||||
|
||||
|
||||
func _on_window_stretch_aspect_item_selected(index):
|
||||
stretch_aspect = index
|
||||
get_tree().set_screen_stretch(stretch_mode, stretch_aspect, base_window_size, scale_factor)
|
||||
|
||||
|
||||
func _on_window_scale_factor_drag_ended(_value_changed):
|
||||
scale_factor = $"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowScaleFactor/HSlider".value
|
||||
$"Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowScaleFactor/Value".text = "%d%%" % (scale_factor * 100)
|
||||
get_tree().set_screen_stretch(stretch_mode, stretch_aspect, base_window_size, scale_factor)
|
||||
276
gui/multiple_resolutions/main.tscn
Normal file
276
gui/multiple_resolutions/main.tscn
Normal file
@@ -0,0 +1,276 @@
|
||||
[gd_scene load_steps=7 format=2]
|
||||
|
||||
[ext_resource path="res://main.gd" type="Script" id=1]
|
||||
[ext_resource path="res://noto_sans_ui_regular.tres" type="DynamicFontData" id=2]
|
||||
|
||||
[sub_resource type="DynamicFont" id=3]
|
||||
size = 14
|
||||
font_data = ExtResource( 2 )
|
||||
|
||||
[sub_resource type="Theme" id=4]
|
||||
default_font = SubResource( 3 )
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=1]
|
||||
draw_center = false
|
||||
border_width_left = 4
|
||||
border_width_top = 4
|
||||
border_width_right = 4
|
||||
border_width_bottom = 4
|
||||
border_color = Color( 0.501961, 1, 0.25098, 0.501961 )
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=2]
|
||||
draw_center = false
|
||||
border_width_left = 8
|
||||
border_width_top = 8
|
||||
border_width_right = 8
|
||||
border_width_bottom = 8
|
||||
border_color = Color( 0.25098, 0.376471, 1, 0.501961 )
|
||||
|
||||
[node name="Main" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
theme = SubResource( 4 )
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="OuterSideLabel" type="Label" parent="."]
|
||||
modulate = Color( 1, 1, 1, 0.627451 )
|
||||
anchor_top = 0.5
|
||||
anchor_bottom = 0.5
|
||||
margin_left = 11.0
|
||||
margin_top = -47.0
|
||||
margin_right = 140.0
|
||||
margin_bottom = -16.0
|
||||
text = "Outer Side Label
|
||||
(ignores all margins)"
|
||||
|
||||
[node name="Panel" type="Panel" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
custom_styles/panel = SubResource( 1 )
|
||||
|
||||
[node name="InnerSideLabel" type="Label" parent="Panel"]
|
||||
modulate = Color( 0.666667, 1, 0.501961, 1 )
|
||||
anchor_top = 0.5
|
||||
anchor_bottom = 0.5
|
||||
margin_left = 11.0
|
||||
margin_top = 16.5
|
||||
margin_right = 209.0
|
||||
margin_bottom = 47.5
|
||||
text = "Inner Side Label
|
||||
(ignores GUI Max Aspect Ratio)"
|
||||
|
||||
[node name="AspectRatioContainer" type="AspectRatioContainer" parent="Panel"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="ColorRect" type="Panel" parent="Panel/AspectRatioContainer"]
|
||||
margin_right = 648.0
|
||||
margin_bottom = 648.0
|
||||
custom_styles/panel = SubResource( 2 )
|
||||
|
||||
[node name="TopLeft" type="ColorRect" parent="Panel/AspectRatioContainer/ColorRect"]
|
||||
margin_right = 64.0
|
||||
margin_bottom = 64.0
|
||||
color = Color( 1, 1, 1, 0.25098 )
|
||||
|
||||
[node name="TopRight" type="ColorRect" parent="Panel/AspectRatioContainer/ColorRect"]
|
||||
anchor_left = 1.0
|
||||
anchor_right = 1.0
|
||||
margin_left = -64.0
|
||||
margin_bottom = 64.0
|
||||
color = Color( 1, 1, 1, 0.25098 )
|
||||
|
||||
[node name="BottomLeft" type="ColorRect" parent="Panel/AspectRatioContainer/ColorRect"]
|
||||
anchor_top = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_top = -64.0
|
||||
margin_right = 64.0
|
||||
color = Color( 1, 1, 1, 0.25098 )
|
||||
|
||||
[node name="BottomRight" type="ColorRect" parent="Panel/AspectRatioContainer/ColorRect"]
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -64.0
|
||||
margin_top = -64.0
|
||||
color = Color( 1, 1, 1, 0.25098 )
|
||||
|
||||
[node name="CenterContainer" type="CenterContainer" parent="Panel/AspectRatioContainer/ColorRect"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
__meta__ = {
|
||||
"_edit_lock_": true
|
||||
}
|
||||
|
||||
[node name="Options" type="VBoxContainer" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer"]
|
||||
margin_left = 167.0
|
||||
margin_top = 187.0
|
||||
margin_right = 481.0
|
||||
margin_bottom = 460.0
|
||||
rect_min_size = Vector2( 300, 0 )
|
||||
custom_constants/separation = 15
|
||||
|
||||
[node name="Title" type="Label" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options"]
|
||||
margin_right = 314.0
|
||||
margin_bottom = 20.0
|
||||
custom_colors/font_color = Color( 1, 0.866667, 0.615686, 1 )
|
||||
text = "Options"
|
||||
align = 1
|
||||
|
||||
[node name="WindowBaseSize" type="HBoxContainer" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options"]
|
||||
margin_top = 35.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 61.0
|
||||
custom_constants/separation = 15
|
||||
|
||||
[node name="Label" type="Label" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowBaseSize"]
|
||||
margin_top = 3.0
|
||||
margin_right = 150.0
|
||||
margin_bottom = 23.0
|
||||
rect_min_size = Vector2( 150, 0 )
|
||||
text = "Window Base Size"
|
||||
|
||||
[node name="OptionButton" type="OptionButton" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowBaseSize"]
|
||||
margin_left = 165.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 26.0
|
||||
size_flags_horizontal = 3
|
||||
text = "648×648 (1:1)"
|
||||
items = [ "648×648 (1:1)", null, false, 0, null, "640×480 (4:3)", null, false, 1, null, "720×480 (3:2)", null, false, 2, null, "800×600 (4:3)", null, false, 3, null, "1152×648 (16:9)", null, false, 5, null, "1280×720 (16:9)", null, false, 6, null, "1280×800 (16:10)", null, false, 7, null, "1680×720 (21:9)", null, false, 8, null ]
|
||||
selected = 0
|
||||
|
||||
[node name="WindowStretchMode" type="HBoxContainer" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options"]
|
||||
margin_top = 76.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 102.0
|
||||
custom_constants/separation = 15
|
||||
|
||||
[node name="Label" type="Label" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowStretchMode"]
|
||||
margin_top = 3.0
|
||||
margin_right = 150.0
|
||||
margin_bottom = 23.0
|
||||
rect_min_size = Vector2( 150, 0 )
|
||||
text = "Window Stretch Mode"
|
||||
|
||||
[node name="OptionButton" type="OptionButton" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowStretchMode"]
|
||||
margin_left = 165.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 26.0
|
||||
size_flags_horizontal = 3
|
||||
text = "2D (Canvas Items)"
|
||||
items = [ "Disabled", null, false, 0, null, "2D (Canvas Items)", null, false, 1, null, "Viewport", null, false, 2, null ]
|
||||
selected = 1
|
||||
|
||||
[node name="WindowStretchAspect" type="HBoxContainer" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options"]
|
||||
margin_top = 117.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 143.0
|
||||
custom_constants/separation = 15
|
||||
|
||||
[node name="Label" type="Label" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowStretchAspect"]
|
||||
margin_top = 3.0
|
||||
margin_right = 155.0
|
||||
margin_bottom = 23.0
|
||||
rect_min_size = Vector2( 150, 0 )
|
||||
text = "Window Stretch Aspect"
|
||||
|
||||
[node name="OptionButton" type="OptionButton" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowStretchAspect"]
|
||||
margin_left = 170.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 26.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Expand"
|
||||
items = [ "Ignore (Distort)", null, false, 0, null, "Keep (Black Bars)", null, false, 1, null, "Keep Width", null, false, 2, null, "Keep Height", null, false, 3, null, "Expand", null, false, 4, null ]
|
||||
selected = 4
|
||||
|
||||
[node name="WindowScaleFactor" type="HBoxContainer" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options"]
|
||||
margin_top = 158.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 178.0
|
||||
custom_constants/separation = 15
|
||||
|
||||
[node name="Label" type="Label" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowScaleFactor"]
|
||||
margin_right = 150.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 150, 0 )
|
||||
text = "Window Scale Factor"
|
||||
|
||||
[node name="HSlider" type="HSlider" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowScaleFactor"]
|
||||
margin_left = 165.0
|
||||
margin_right = 263.0
|
||||
margin_bottom = 16.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 100.0
|
||||
min_value = 0.75
|
||||
max_value = 2.0
|
||||
step = 0.01
|
||||
value = 1.0
|
||||
|
||||
[node name="Value" type="Label" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowScaleFactor"]
|
||||
margin_left = 278.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 20.0
|
||||
size_flags_horizontal = 3
|
||||
text = "100%"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options"]
|
||||
margin_top = 193.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 197.0
|
||||
|
||||
[node name="GUIMaxAspectRatio" type="HBoxContainer" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options"]
|
||||
margin_top = 212.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 238.0
|
||||
custom_constants/separation = 15
|
||||
|
||||
[node name="Label" type="Label" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMaxAspectRatio"]
|
||||
margin_top = 3.0
|
||||
margin_right = 150.0
|
||||
margin_bottom = 23.0
|
||||
rect_min_size = Vector2( 150, 0 )
|
||||
text = "GUI Max Aspect Ratio"
|
||||
|
||||
[node name="OptionButton" type="OptionButton" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMaxAspectRatio"]
|
||||
margin_left = 165.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 26.0
|
||||
size_flags_horizontal = 3
|
||||
text = "Fit to Window"
|
||||
items = [ "Fit to Window", null, false, 0, null, "5:4", null, false, 1, null, "4:3", null, false, 2, null, "3:2", null, false, 3, null, "16:10", null, false, 4, null, "16:9", null, false, 5, null, "21:9", null, false, 6, null ]
|
||||
selected = 0
|
||||
|
||||
[node name="GUIMargin" type="HBoxContainer" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options"]
|
||||
margin_top = 253.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 273.0
|
||||
custom_constants/separation = 15
|
||||
|
||||
[node name="Label" type="Label" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMargin"]
|
||||
margin_right = 150.0
|
||||
margin_bottom = 20.0
|
||||
rect_min_size = Vector2( 150, 0 )
|
||||
text = "GUI Margin"
|
||||
|
||||
[node name="HSlider" type="HSlider" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMargin"]
|
||||
margin_left = 165.0
|
||||
margin_right = 291.0
|
||||
margin_bottom = 16.0
|
||||
size_flags_horizontal = 3
|
||||
size_flags_stretch_ratio = 100.0
|
||||
max_value = 50.0
|
||||
|
||||
[node name="Value" type="Label" parent="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMargin"]
|
||||
margin_left = 306.0
|
||||
margin_right = 314.0
|
||||
margin_bottom = 20.0
|
||||
size_flags_horizontal = 3
|
||||
text = "0"
|
||||
|
||||
[connection signal="item_selected" from="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowBaseSize/OptionButton" to="." method="_on_window_base_size_item_selected"]
|
||||
[connection signal="item_selected" from="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowStretchMode/OptionButton" to="." method="_on_window_stretch_mode_item_selected"]
|
||||
[connection signal="item_selected" from="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowStretchAspect/OptionButton" to="." method="_on_window_stretch_aspect_item_selected"]
|
||||
[connection signal="drag_ended" from="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/WindowScaleFactor/HSlider" to="." method="_on_window_scale_factor_drag_ended"]
|
||||
[connection signal="item_selected" from="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMaxAspectRatio/OptionButton" to="." method="_on_gui_aspect_ratio_item_selected"]
|
||||
[connection signal="drag_ended" from="Panel/AspectRatioContainer/ColorRect/CenterContainer/Options/GUIMargin/HSlider" to="." method="_on_gui_margin_drag_ended"]
|
||||
5
gui/multiple_resolutions/noto_sans_ui_regular.tres
Normal file
5
gui/multiple_resolutions/noto_sans_ui_regular.tres
Normal file
@@ -0,0 +1,5 @@
|
||||
[gd_resource type="DynamicFontData" format=2]
|
||||
|
||||
[resource]
|
||||
hinting = 1
|
||||
font_path = "res://noto_sans_ui_regular.ttf"
|
||||
BIN
gui/multiple_resolutions/noto_sans_ui_regular.ttf
Normal file
BIN
gui/multiple_resolutions/noto_sans_ui_regular.ttf
Normal file
Binary file not shown.
48
gui/multiple_resolutions/project.godot
Normal file
48
gui/multiple_resolutions/project.godot
Normal file
@@ -0,0 +1,48 @@
|
||||
; Engine configuration file.
|
||||
; It's best edited using the editor UI and not directly,
|
||||
; since the parameters that go here are not all obvious.
|
||||
;
|
||||
; Format:
|
||||
; [section] ; section goes between []
|
||||
; param=value ; assign values to parameters
|
||||
|
||||
config_version=4
|
||||
|
||||
[application]
|
||||
|
||||
config/name="Multiple Resolutions and Aspect Ratios"
|
||||
config/description="This project demonstrates how to set up a project to handle screens of
|
||||
multiple resolutions and aspect ratios.
|
||||
|
||||
The GUI can be made to fit the window or constrained to a specific
|
||||
aspect ratio from a list of common aspect ratios. On ultrawide aspect ratios,
|
||||
this can be used to prevent HUD elements from being too spread apart,
|
||||
which can harm the gameplay experience.
|
||||
|
||||
For non-essential HUD elements, specific controls can be made to
|
||||
ignore this aspect ratio constraint when it makes sense
|
||||
(e.g. a list of players on the side of the screen).
|
||||
|
||||
Additionally, a GUI margin setting is provided to better handle TVs
|
||||
with an overscan area to prevent GUI elements from being cut off.
|
||||
This can also improve the gameplay experience on large monitors
|
||||
by bringing HUD elements closer to the center of the screen."
|
||||
run/main_scene="res://main.tscn"
|
||||
run/low_processor_mode=true
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[display]
|
||||
|
||||
window/size/width=648
|
||||
window/size/height=648
|
||||
window/size/test_width=1152
|
||||
window/size/test_height=648
|
||||
window/dpi/allow_hidpi=true
|
||||
window/handheld/orientation="sensor"
|
||||
window/stretch/mode="2d"
|
||||
window/stretch/aspect="expand"
|
||||
|
||||
[rendering]
|
||||
|
||||
quality/driver/driver_name="GLES2"
|
||||
environment/default_clear_color=Color( 0.133333, 0.133333, 0.2, 1 )
|
||||
0
gui/multiple_resolutions/screenshots/.gdignore
Normal file
0
gui/multiple_resolutions/screenshots/.gdignore
Normal file
BIN
gui/multiple_resolutions/screenshots/multiple_resolutions.png
Normal file
BIN
gui/multiple_resolutions/screenshots/multiple_resolutions.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
Reference in New Issue
Block a user