From fba0394e7b4550277018a94a9060090ed47d0d59 Mon Sep 17 00:00:00 2001 From: nuts_rice Date: Mon, 30 Mar 2026 13:17:41 -0600 Subject: [PATCH 1/7] feat(bevy_city): add trafficLight struct WIP --- examples/large_scenes/bevy_city/Cargo.toml | 4 + examples/large_scenes/bevy_city/src/main.rs | 33 +++- .../large_scenes/bevy_city/src/traffic.rs | 142 ++++++++++++++++++ .../bevy_city/traffic_assets/street_light.glb | Bin 0 -> 7492 bytes 4 files changed, 171 insertions(+), 8 deletions(-) create mode 100644 examples/large_scenes/bevy_city/src/traffic.rs create mode 100644 examples/large_scenes/bevy_city/traffic_assets/street_light.glb diff --git a/examples/large_scenes/bevy_city/Cargo.toml b/examples/large_scenes/bevy_city/Cargo.toml index deb64ecaa04ea..649096c0171e1 100644 --- a/examples/large_scenes/bevy_city/Cargo.toml +++ b/examples/large_scenes/bevy_city/Cargo.toml @@ -5,6 +5,10 @@ edition = "2024" publish = false license = "MIT OR Apache-2.0" +[features] +trace_tracy = ["bevy/trace_tracy"] +traffic = [] + [dependencies] bevy = { path = "../../../", features = [ "https", diff --git a/examples/large_scenes/bevy_city/src/main.rs b/examples/large_scenes/bevy_city/src/main.rs index 24d53893ecc31..49490d2c77ee1 100644 --- a/examples/large_scenes/bevy_city/src/main.rs +++ b/examples/large_scenes/bevy_city/src/main.rs @@ -15,6 +15,10 @@ use bevy::{ }, post_process::bloom::Bloom, prelude::*, + render::{ + settings::{Backends, InstanceFlags, RenderCreation, WgpuSettings}, + RenderPlugin, + }, scene::SceneInstanceReady, window::{PresentMode, WindowResolution}, winit::WinitSettings, @@ -27,6 +31,10 @@ mod assets; mod generate_city; mod settings; +#[cfg(feature = "traffic")] +mod traffic; + + #[derive(FromArgs, Resource, Clone)] /// Config pub struct Args { @@ -41,23 +49,32 @@ pub struct Args { /// adds NoCpuCulling to all meshes #[argh(switch)] no_cpu_culling: bool, + + /// forces Vulkan backend and clears instance flags for RenderDoc capture + #[argh(switch)] + renderdoc: bool, } fn main() { let args: Args = argh::from_env(); + App::new() .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "bevy_city".into(), - resolution: WindowResolution::new(1920, 1080).with_scale_factor_override(1.0), - present_mode: PresentMode::AutoNoVsync, - position: WindowPosition::Centered(MonitorSelection::Primary), + DefaultPlugins + .set(WindowPlugin { + primary_window: Some(Window { + title: "bevy_city".into(), + resolution: WindowResolution::new(1920, 1080) + .with_scale_factor_override(1.0), + present_mode: PresentMode::AutoNoVsync, + position: WindowPosition::Centered(MonitorSelection::Primary), + ..default() + }), ..default() }), - ..default() - }), + #[cfg(feature = "traffic")] + traffic_light::TrafficLightPlugin, FreeCameraPlugin, FeathersPlugins, WireframePlugin::default(), diff --git a/examples/large_scenes/bevy_city/src/traffic.rs b/examples/large_scenes/bevy_city/src/traffic.rs new file mode 100644 index 0000000000000..ff2f88d80e7bd --- /dev/null +++ b/examples/large_scenes/bevy_city/src/traffic.rs @@ -0,0 +1,142 @@ +use bevy::{prelude::*, scene::SceneInstanceReady}; + +pub const RED_DURATION: f32 = 5.0; +pub const YELLOW_DURATION: f32 = 2.0; +pub const GREEN_DURATION: f32 = 5.0; + +// Timing phase logic for traffic light +pub enum TrafficLightPhase { + Red, + Yellow, + Green, +} + +pub struct TrafficLight { + pub time_offset: f32, +} + + +impl TrafficLight { + pub fn new(time_offset: f32) -> Self { + Self { time_offset } + } + + pub fn phase(&self, time: f32) -> TrafficLightPhase { + let cycle_time = RED_DURATION + YELLOW_DURATION + GREEN_DURATION; + let time_in_cycle = (time + self.time_offset) % cycle_time; + + if time_in_cycle < RED_DURATION { + TrafficLightPhase::Red + } else if time_in_cycle < RED_DURATION + YELLOW_DURATION { + TrafficLightPhase::Yellow + } else { + TrafficLightPhase::Green + } + } + + +} +// Component/material for bulb +pub enum TrafficLightColor { + Red, + Yellow, + Green, +} + +#[define(Component)] +pub struct TrafficLightBulb { + pub color: TrafficLightColor, + pub light_entity: Entity, + pub last_phase: Option, +} + + +// should it be red_on, yellow_on, etc...? +#[define(Resource)] +pub struct TrafficLightMaterials { + pub red: Handle, + pub yellow: Handle, + pub green: Handle, + +} + +pub struct TrafficPlugin; + +impl Plugin for TrafficPlugin { + fn build(&self, app: &mut App) { + app.add_system(Self::update_traffic_lights); + } +} + +fn setup_traffic_light_materials(mut commands: Commands, mut materials: ResMut>) { + let red_material = materials.add(StandardMaterial { + base_color: Color::rgb(1.0, 0.0, 0.0), + emissive: Color::rgb(1.0, 0.0, 0.0), + ..Default::default() + }); + let yellow_material = materials.add(StandardMaterial { + base_color: Color::rgb(1.0, 1.0, 0.0), + emissive: Color::rgb(1.0, 1.0, 0.0), + ..Default::default() + }); + let green_material = materials.add(StandardMaterial { + base_color: Color::rgb(0.0, 1.0, 0.0), + emissive: Color::rgb(0.0, 1.0, 0.0), + ..Default::default() + }); + + commands.insert_resource(TrafficLightMaterials { + red: red_material, + yellow: yellow_material, + green: green_material, + }); + + +} + +fn on_traffic_light_scene_ready( + mut commands: Commands, + mut ready_events: EventReader, + materials: Res, +) { + for event in ready_events.iter() { + if event.scene_handle == "traffic_light_scene_handle" { + let traffic_light_entity = event.instance_id; + let red_bulb_entity = commands.spawn().insert(TrafficLightBulb { + color: TrafficLightColor::Red, + light_entity: traffic_light_entity, + last_phase: None, + }).id(); + let yellow_bulb_entity = commands.spawn().insert(TrafficLightBulb { + color: TrafficLightColor::Yellow, + light_entity: traffic_light_entity, + last_phase: None, + }).id(); + let green_bulb_entity = commands.spawn().insert(TrafficLightBulb { + color: TrafficLightColor::Green, + light_entity: traffic_light_entity, + last_phase: None, + }).id(); + + commands.entity(red_bulb_entity).insert(materials.red.clone()); + commands.entity(yellow_bulb_entity).insert(materials.yellow.clone()); + commands.entity(green_bulb_entity).insert(materials.green.clone()); + } + } +} + +fn update_bulb_materials(mut bulbs: Query<(Entity, &mut TrafficLightBulbMaterial)>, traffic_lights: Query<&TrafficLight>, time: Res