docs/bevy/examples/time/timers.rs 2.4 K · 77 lines · raw · history

1 //! Illustrates how `Timer`s can be used both as resources and components.
2
3 use bevy::{log::info, prelude::*};
4
5 fn main() {
6 App::new()
7 .add_plugins(DefaultPlugins)
8 .init_resource::<Countdown>()
9 .add_systems(Startup, setup)
10 .add_systems(Update, (countdown, print_when_completed))
11 .run();
12 }
13
14 #[derive(Component, Deref, DerefMut)]
15 struct PrintOnCompletionTimer(Timer);
16
17 #[derive(Resource)]
18 struct Countdown {
19 percent_trigger: Timer,
20 main_timer: Timer,
21 }
22
23 impl Countdown {
24 pub fn new() -> Self {
25 Self {
26 percent_trigger: Timer::from_seconds(4.0, TimerMode::Repeating),
27 main_timer: Timer::from_seconds(20.0, TimerMode::Once),
28 }
29 }
30 }
31
32 impl Default for Countdown {
33 fn default() -> Self {
34 Self::new()
35 }
36 }
37
38 fn setup(mut commands: Commands) {
39 // Add an entity to the world with a timer
40 commands.spawn(PrintOnCompletionTimer(Timer::from_seconds(
41 5.0,
42 TimerMode::Once,
43 )));
44 }
45
46 /// This system ticks the `Timer` on the entity with the `PrintOnCompletionTimer`
47 /// component using bevy's `Time` resource to get the delta between each update.
48 fn print_when_completed(time: Res<Time>, mut query: Query<&mut PrintOnCompletionTimer>) {
49 for mut timer in &mut query {
50 if timer.tick(time.delta()).just_finished() {
51 info!("Entity timer just finished");
52 }
53 }
54 }
55
56 /// This system controls ticking the timer within the countdown resource and
57 /// handling its state.
58 fn countdown(time: Res<Time>, mut countdown: ResMut<Countdown>) {
59 countdown.main_timer.tick(time.delta());
60
61 // The API encourages this kind of timer state checking (if you're only checking for one value)
62 // Additionally, `is_finished()` would accomplish the same thing as `just_finished` due to the
63 // timer being repeating, however this makes more sense visually.
64 if countdown.percent_trigger.tick(time.delta()).just_finished() {
65 if !countdown.main_timer.is_finished() {
66 // Print the percent complete the main timer is.
67 info!(
68 "Timer is {:0.0}% complete!",
69 countdown.main_timer.fraction() * 100.0
70 );
71 } else {
72 // The timer has finished so we pause the percent output timer
73 countdown.percent_trigger.pause();
74 info!("Paused percent trigger timer");
75 }
76 }
77 }