1- //! This example demonstrates Bevy's visual debugging using retained gizmos.
1+ //! This example demonstrates retained gizmos.
22
33use bevy:: {
44 camera_controller:: free_camera:: { FreeCamera , FreeCameraPlugin } ,
55 color:: palettes:: css:: * ,
66 prelude:: * ,
77} ;
8+ use rand:: Rng ;
89
910fn main ( ) {
1011 App :: new ( )
1112 . add_plugins ( ( DefaultPlugins , FreeCameraPlugin ) )
12- //.init_gizmo_group::<MyRoundGizmos>()
1313 . add_systems ( Startup , setup)
14- // .add_systems(
15- // Update,
16- // (
17- // draw_example_collection,
18- // update_config,
19- // update_retained_gizmo_visibility,
20- // ),
21- // )
14+ . add_systems ( Update , ( spawn_gizmo, spin, twinkle) )
15+ . add_observer ( on_spawn_gizmo)
2216 . run ( ) ;
2317}
2418
25- fn setup ( mut commands : Commands , mut gizmo_assets : ResMut < Assets < GizmoAsset > > ) {
19+ fn setup ( mut commands : Commands ) {
2620 commands. spawn ( (
21+ Camera {
22+ clear_color : ClearColorConfig :: Custom ( BLACK . into ( ) ) ,
23+ ..default ( )
24+ } ,
2725 Camera3d :: default ( ) ,
28- Transform :: from_xyz ( 0. , 1.5 , 6. ) . looking_at ( Vec3 :: NEG_Z , Vec3 :: Y ) ,
26+ Transform :: from_xyz ( 0. , 0. , 6. ) . looking_at ( Vec3 :: NEG_Z , Vec3 :: Y ) ,
2927 FreeCamera :: default ( ) ,
3028 ) ) ;
29+ }
30+
31+ const COLORS : [ Srgba ; 7 ] = [
32+ CORNSILK ,
33+ DARK_ORANGE ,
34+ MEDIUM_AQUAMARINE ,
35+ CORAL ,
36+ BISQUE ,
37+ ANTIQUE_WHITE ,
38+ BLUE_VIOLET ,
39+ ] ;
40+
41+ #[ derive( Component ) ]
42+ struct Spin ( f32 ) ;
43+
44+ #[ derive( Component ) ]
45+ struct Twinkler {
46+ timer : Timer ,
47+ not_before : f32 ,
48+ }
49+
50+ #[ derive( Deref , DerefMut ) ]
51+ struct SpawnTimer ( Timer ) ;
52+
53+ impl Default for SpawnTimer {
54+ fn default ( ) -> Self {
55+ SpawnTimer ( Timer :: from_seconds ( 0.1 , TimerMode :: Once ) )
56+ }
57+ }
58+
59+ fn spawn_gizmo (
60+ mut commands : Commands ,
61+ mut timer : Local < SpawnTimer > ,
62+ gizmos : Query < Entity , With < Gizmo > > ,
63+ time : Res < Time > ,
64+ ) {
65+ timer. tick ( time. delta ( ) ) ;
66+ if !timer. just_finished ( ) {
67+ return ;
68+ }
69+ let mut rng = rand:: rng ( ) ;
70+ * * timer = Timer :: from_seconds ( rng. random_range ( 1.2 ..3.8 ) , TimerMode :: Once ) ;
71+
72+ let total = gizmos. iter ( ) . count ( ) ;
3173
74+ if total > 25 && rng. random_bool ( ( total as f64 / 150.0 ) . min ( 1.0 ) ) {
75+ if let Some ( entity) = gizmos. iter ( ) . nth ( rng. random_range ( 0 ..total) ) {
76+ commands. entity ( entity) . despawn ( ) ;
77+ }
78+ return ;
79+ }
80+
81+ commands. trigger ( SpawnGizmo ) ;
82+ }
83+
84+ #[ derive( Event ) ]
85+ struct SpawnGizmo ;
86+
87+ fn on_spawn_gizmo (
88+ _: On < SpawnGizmo > ,
89+ mut commands : Commands ,
90+ mut gizmo_assets : ResMut < Assets < GizmoAsset > > ,
91+ ) {
3292 let mut gizmo = GizmoAsset :: new ( ) ;
3393
94+ let mut rng = rand:: rng ( ) ;
95+ let radius = rng. random_range ( 0.5 ..2.0 ) ;
96+ let x = rng. random_range ( -31.0 ..31.0 ) ;
97+ let y = rng. random_range ( -17.0 ..17.0 ) ;
98+ let z = rng. random_range ( -50.0 ..-30.0 ) ;
99+ let axis = Vec3 :: new (
100+ rng. random_range ( -1.0 ..1.0 ) ,
101+ rng. random_range ( -1.0 ..1.0 ) ,
102+ rng. random_range ( -1.0 ..1.0 ) ,
103+ )
104+ . normalize_or ( Vec3 :: Y ) ;
105+ let up = axis. any_orthonormal_vector ( ) ;
106+ let spin_rate = rng. random_range ( -0.5 ..0.5 ) ;
107+
34108 // When drawing a lot of static lines a Gizmo component can have
35109 // far better performance than the Gizmos system parameter,
36110 // but the system parameter will perform better for smaller lines that update often.
37-
38- // we'll sprinkle spheres made of 3,000 lines throughout the scene
39- // and make the blink
111+ let color = COLORS [ rng. random_range ( 0 ..COLORS . len ( ) ) ] ;
40112 gizmo
41- . sphere ( Isometry3d :: IDENTITY , 0.5 , LIGHT_GOLDENROD_YELLOW )
113+ . sphere ( Isometry3d :: IDENTITY , radius , color )
42114 . resolution ( 3_000 / 3 ) ;
43115
116+ let color = COLORS [ rng. random_range ( 0 ..COLORS . len ( ) ) ] ;
117+ gizmo. cross ( Isometry3d :: IDENTITY , radius, color) ;
118+
44119 commands. spawn ( (
45120 Gizmo {
46121 handle : gizmo_assets. add ( gizmo) ,
@@ -50,6 +125,37 @@ fn setup(mut commands: Commands, mut gizmo_assets: ResMut<Assets<GizmoAsset>>) {
50125 } ,
51126 ..default ( )
52127 } ,
53- Transform :: IDENTITY ,
128+ Transform :: from_translation ( vec3 ( x, y, z) ) . looking_to ( axis, up) ,
129+ Spin ( spin_rate) ,
54130 ) ) ;
55131}
132+
133+ fn spin ( mut spinners : Query < ( & mut Transform , & Spin ) > , time : Res < Time > ) {
134+ for ( mut transform, spin) in & mut spinners {
135+ transform. rotate_local_y ( time. delta_secs ( ) * spin. 0 ) ;
136+ }
137+ }
138+
139+ fn twinkle (
140+ mut commands : Commands ,
141+ mut gizmos : Query < ( Entity , & mut Visibility , Option < & mut Twinkler > ) , With < Gizmo > > ,
142+ time : Res < Time > ,
143+ ) {
144+ for ( entity, mut visibility, twinkler) in & mut gizmos {
145+ if let Some ( mut twinkler) = twinkler {
146+ twinkler. timer . tick ( time. delta ( ) ) ;
147+ if twinkler. timer . just_finished ( ) {
148+ * visibility = Visibility :: Visible ;
149+ }
150+ if twinkler. not_before < time. elapsed_secs ( ) {
151+ commands. entity ( entity) . remove :: < Twinkler > ( ) ;
152+ }
153+ } else if rand:: rng ( ) . random_bool ( 0.001 ) {
154+ * visibility = Visibility :: Hidden ;
155+ commands. entity ( entity) . insert ( Twinkler {
156+ timer : Timer :: from_seconds ( rand:: rng ( ) . random_range ( 0.3 ..0.8 ) , TimerMode :: Once ) ,
157+ not_before : time. elapsed_secs ( ) + rand:: rng ( ) . random_range ( 5.0 ..15.0 ) ,
158+ } ) ;
159+ }
160+ }
161+ }
0 commit comments