Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/examples/ui/text.rs
6595 views
1
//! This example illustrates how to create UI text and update it in a system.
2
//!
3
//! It displays the current FPS in the top left corner, as well as text that changes color
4
//! in the bottom right. For text within a scene, please see the text2d example.
5
6
use bevy::{
7
color::palettes::css::GOLD,
8
diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin},
9
prelude::*,
10
};
11
12
fn main() {
13
App::new()
14
.add_plugins((DefaultPlugins, FrameTimeDiagnosticsPlugin::default()))
15
.add_systems(Startup, setup)
16
.add_systems(Update, (text_update_system, text_color_system))
17
.run();
18
}
19
20
// Marker struct to help identify the FPS UI component, since there may be many Text components
21
#[derive(Component)]
22
struct FpsText;
23
24
// Marker struct to help identify the color-changing Text component
25
#[derive(Component)]
26
struct AnimatedText;
27
28
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {
29
// UI camera
30
commands.spawn(Camera2d);
31
// Text with one section
32
commands.spawn((
33
// Accepts a `String` or any type that converts into a `String`, such as `&str`
34
Text::new("hello\nbevy!"),
35
TextFont {
36
// This font is loaded and will be used instead of the default font.
37
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
38
font_size: 67.0,
39
..default()
40
},
41
TextShadow::default(),
42
// Set the justification of the Text
43
TextLayout::new_with_justify(Justify::Center),
44
// Set the style of the Node itself.
45
Node {
46
position_type: PositionType::Absolute,
47
bottom: px(5),
48
right: px(5),
49
..default()
50
},
51
AnimatedText,
52
));
53
54
// Text with multiple sections
55
commands
56
.spawn((
57
// Create a Text with multiple child spans.
58
Text::new("FPS: "),
59
TextFont {
60
// This font is loaded and will be used instead of the default font.
61
font: asset_server.load("fonts/FiraSans-Bold.ttf"),
62
font_size: 42.0,
63
..default()
64
},
65
))
66
.with_child((
67
TextSpan::default(),
68
if cfg!(feature = "default_font") {
69
(
70
TextFont {
71
font_size: 33.0,
72
// If no font is specified, the default font (a minimal subset of FiraMono) will be used.
73
..default()
74
},
75
TextColor(GOLD.into()),
76
)
77
} else {
78
(
79
// "default_font" feature is unavailable, load a font to use instead.
80
TextFont {
81
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
82
font_size: 33.0,
83
..Default::default()
84
},
85
TextColor(GOLD.into()),
86
)
87
},
88
FpsText,
89
));
90
91
#[cfg(feature = "default_font")]
92
commands.spawn((
93
// Here we are able to call the `From` method instead of creating a new `TextSection`.
94
// This will use the default font (a minimal subset of FiraMono) and apply the default styling.
95
Text::new("From an &str into a Text with the default font!"),
96
Node {
97
position_type: PositionType::Absolute,
98
bottom: px(5),
99
left: px(15),
100
..default()
101
},
102
));
103
104
#[cfg(not(feature = "default_font"))]
105
commands.spawn((
106
Text::new("Default font disabled"),
107
TextFont {
108
font: asset_server.load("fonts/FiraMono-Medium.ttf"),
109
..default()
110
},
111
Node {
112
position_type: PositionType::Absolute,
113
bottom: px(5),
114
left: px(15),
115
..default()
116
},
117
));
118
}
119
120
fn text_color_system(time: Res<Time>, mut query: Query<&mut TextColor, With<AnimatedText>>) {
121
for mut text_color in &mut query {
122
let seconds = time.elapsed_secs();
123
124
// Update the color of the ColorText span.
125
text_color.0 = Color::srgb(
126
ops::sin(1.25 * seconds) / 2.0 + 0.5,
127
ops::sin(0.75 * seconds) / 2.0 + 0.5,
128
ops::sin(0.50 * seconds) / 2.0 + 0.5,
129
);
130
}
131
}
132
133
fn text_update_system(
134
diagnostics: Res<DiagnosticsStore>,
135
mut query: Query<&mut TextSpan, With<FpsText>>,
136
) {
137
for mut span in &mut query {
138
if let Some(fps) = diagnostics.get(&FrameTimeDiagnosticsPlugin::FPS)
139
&& let Some(value) = fps.smoothed()
140
{
141
// Update the value of the second section
142
**span = format!("{value:.2}");
143
}
144
}
145
}
146
147