Open
Description
Bevy version
0.15.0
Relevant system information
AdapterInfo { name: "NVIDIA GeForce RTX 4070 SUPER", vendor: 4318, device: 10115, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "565.90", backend: Vulkan }
What you did
There is a white button. When you press it, it becomes black with a transition in 0.2 s. This is a desktop app, so I need to send RequestRedraw
manually. If the transition has not finished, it will call redraw_request_events.send(RequestRedraw)
, so this system will still be called to redraw next frame.
fn update_background_color(
mut buttons: Query<(&mut CustomButton, &mut BackgroundColor)>,
mut redraw_request_events: EventWriter<RequestRedraw>,
) {
for (mut button, mut background_color) in buttons.iter_mut() {
if let Some(transition) = &button.transition {
/// Unit: second
const TRANSITION_DURATION: f32 = 0.2;
let t = transition.start_time.elapsed().unwrap().as_secs_f32();
info!("t = {t} s");
if t > TRANSITION_DURATION {
button.transition = None;
info!("transition finished");
continue;
}
let y = EasingCurve::new(0.0, 1.0, EaseFunction::SineIn)
.sample(t / TRANSITION_DURATION)
.unwrap();
background_color.0 = transition.start.mix(&transition.end, y);
redraw_request_events.send(RequestRedraw);
}
}
}
However, the output is:
2024-12-14T09:16:26.746642Z INFO bevy_demo: t = 0.0000055 s
2024-12-14T09:16:27.136166Z INFO bevy_demo: t = 0.3895302 s
2024-12-14T09:16:27.136300Z INFO bevy_demo: transition finished
It shows that nearly 400ms after 09:16:26.746642
, the next redraw is called.
Click me to expand the `main.rs`
use bevy::{prelude::*, window::RequestRedraw, winit::WinitSettings};
use std::time::SystemTime;
const DEFAULT_BUTTON_BACKGROUND_COLOR: Color = Color::WHITE;
const PRESSED_BUTTON_BACKGROUND_COLOR: Color = Color::BLACK;
#[derive(Component)]
#[require(
Button,
BackgroundColor(|| BackgroundColor(DEFAULT_BUTTON_BACKGROUND_COLOR)),
)]
pub struct CustomButton {
transition: Option<Transition>,
}
struct Transition {
start: Color,
end: Color,
start_time: std::time::SystemTime,
}
fn on_interaction(
mut buttons: Query<(&mut CustomButton, &BackgroundColor, &Interaction), Changed<Interaction>>,
) {
for (mut button, background_color, interaction) in buttons.iter_mut() {
match interaction {
Interaction::Pressed => {
button.transition = Some(Transition {
start: background_color.0,
end: PRESSED_BUTTON_BACKGROUND_COLOR,
start_time: SystemTime::now(),
});
}
Interaction::None => {
button.transition = Some(Transition {
start: background_color.0,
end: DEFAULT_BUTTON_BACKGROUND_COLOR,
start_time: SystemTime::now(),
});
}
_ => {}
}
}
}
fn update_background_color(
mut buttons: Query<(&mut CustomButton, &mut BackgroundColor)>,
mut redraw_request_events: EventWriter<RequestRedraw>,
) {
for (mut button, mut background_color) in buttons.iter_mut() {
if let Some(transition) = &button.transition {
/// Unit: second
const TRANSITION_DURATION: f32 = 0.2;
let t = transition.start_time.elapsed().unwrap().as_secs_f32();
info!("t = {t} s");
if t > TRANSITION_DURATION {
button.transition = None;
info!("transition finished");
continue;
}
let y = EasingCurve::new(0.0, 1.0, EaseFunction::SineIn)
.sample(t / TRANSITION_DURATION)
.unwrap();
background_color.0 = transition.start.mix(&transition.end, y);
redraw_request_events.send(RequestRedraw);
}
}
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2d);
commands.spawn((
CustomButton {
transition: None,
},
Node {
width: Val::Px(200.0),
height: Val::Px(100.0),
..default()
},
));
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.insert_resource(WinitSettings::desktop_app())
.add_systems(Startup, setup)
.add_systems(Update, (on_interaction, update_background_color))
.run();
}
What went wrong
It should be like this:
2024-12-14T09:16:13.352178Z INFO bevy_demo: t = 0.0000044 s
2024-12-14T09:16:13.360099Z INFO bevy_demo: t = 0.0079271 s
2024-12-14T09:16:13.360687Z INFO bevy_demo: t = 0.0085149 s
2024-12-14T09:16:13.361251Z INFO bevy_demo: t = 0.0090788 s
// ...
2024-12-14T09:16:13.540491Z INFO bevy_demo: t = 0.1883187 s
2024-12-14T09:16:13.544745Z INFO bevy_demo: t = 0.19257231 s
2024-12-14T09:16:13.550594Z INFO bevy_demo: t = 0.19842151 s
2024-12-14T09:16:13.556571Z INFO bevy_demo: t = 0.2043975 s
2024-12-14T09:16:13.556679Z INFO bevy_demo: transition finished