Skip to content

Commit 1d6e53d

Browse files
meepleekRay Redondo
authored and
Ray Redondo
committed
add on_real_time_timer run condition (bevyengine#10179)
# Objective Fixes bevyengine#10177 . ## Solution Added a new run condition and tweaked the docs for `on_timer`. ## Changelog ### Added - `on_real_time_timer` run condition
1 parent 240866d commit 1d6e53d

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

crates/bevy_time/src/common_conditions.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
use crate::{Time, Timer, TimerMode};
1+
use crate::{Real, Time, Timer, TimerMode};
22
use bevy_ecs::system::Res;
33
use bevy_utils::Duration;
44

55
/// Run condition that is active on a regular time interval, using [`Time`] to advance
6-
/// the timer.
6+
/// the timer. The timer ticks at the rate of [`Time::relative_speed`].
77
///
88
/// ```rust,no_run
99
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup, Update};
@@ -38,6 +38,42 @@ pub fn on_timer(duration: Duration) -> impl FnMut(Res<Time>) -> bool + Clone {
3838
}
3939
}
4040

41+
/// Run condition that is active on a regular time interval, using [`Time<Real>`] to advance
42+
/// the timer. The timer ticks are not scaled.
43+
///
44+
/// ```rust,no_run
45+
/// # use bevy_app::{App, NoopPluginGroup as DefaultPlugins, PluginGroup, Update};
46+
/// # use bevy_ecs::schedule::IntoSystemConfigs;
47+
/// # use bevy_utils::Duration;
48+
/// # use bevy_time::common_conditions::on_real_timer;
49+
/// fn main() {
50+
/// App::new()
51+
/// .add_plugins(DefaultPlugins)
52+
/// .add_systems(Update, tick.run_if(on_real_timer(Duration::from_secs(1))))
53+
/// .run();
54+
/// }
55+
/// fn tick() {
56+
/// // ran once a second
57+
/// }
58+
/// ```
59+
///
60+
/// Note that this does **not** guarantee that systems will run at exactly the
61+
/// specified interval. If delta time is larger than the specified `duration` then
62+
/// the system will only run once even though the timer may have completed multiple
63+
/// times. This condition should only be used with large time durations (relative to
64+
/// delta time).
65+
///
66+
/// For more accurate timers, use the [`Timer`] class directly (see
67+
/// [`Timer::times_finished_this_tick`] to address the problem mentioned above), or
68+
/// use fixed timesteps that allow systems to run multiple times per frame.
69+
pub fn on_real_timer(duration: Duration) -> impl FnMut(Res<Time<Real>>) -> bool + Clone {
70+
let mut timer = Timer::new(duration, TimerMode::Repeating);
71+
move |time: Res<Time<Real>>| {
72+
timer.tick(time.delta());
73+
timer.just_finished()
74+
}
75+
}
76+
4177
#[cfg(test)]
4278
mod tests {
4379
use super::*;

0 commit comments

Comments
 (0)