Merge branch 'main' into ignore_transparancy_on_sprite_picking

This commit is contained in:
Michael Walter Van Der Velden 2024-11-19 09:59:16 +00:00 committed by GitHub
commit 71f9383a8b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 256 additions and 57 deletions

View file

@ -1,4 +1,5 @@
use bevy_ecs::{event::Event, prelude::Entity}; use bevy_ecs::{event::Event, prelude::Entity};
#[cfg(feature = "reflect")]
use bevy_reflect::Reflect; use bevy_reflect::Reflect;
/// An [`Event`] that is fired whenever there is a change in the world's hierarchy. /// An [`Event`] that is fired whenever there is a change in the world's hierarchy.

View file

@ -210,7 +210,17 @@ where
/// Returns `true` if any item in `inputs` has just been released. /// Returns `true` if any item in `inputs` has just been released.
pub fn any_just_released(&self, inputs: impl IntoIterator<Item = T>) -> bool { pub fn any_just_released(&self, inputs: impl IntoIterator<Item = T>) -> bool {
inputs.into_iter().any(|it| self.just_released(it)) inputs.into_iter().any(|input| self.just_released(input))
}
/// Returns `true` if all items in `inputs` have just been released.
pub fn all_just_released(&self, inputs: impl IntoIterator<Item = T>) -> bool {
inputs.into_iter().all(|input| self.just_released(input))
}
/// Returns `true` if all items in `inputs` have been just pressed.
pub fn all_just_pressed(&self, inputs: impl IntoIterator<Item = T>) -> bool {
inputs.into_iter().all(|input| self.just_pressed(input))
} }
/// Clears the `just_released` state of the `input` and returns `true` if the `input` has just been released. /// Clears the `just_released` state of the `input` and returns `true` if the `input` has just been released.

View file

@ -307,7 +307,7 @@ pub enum ButtonSettingsError {
}, },
} }
/// Stores a connected gamepad's state and any metadata such as the device name. /// Stores a connected gamepad's metadata such as the name and its [`GamepadButton`] and [`GamepadAxis`].
/// ///
/// An entity with this component is spawned automatically after [`GamepadConnectionEvent`] /// An entity with this component is spawned automatically after [`GamepadConnectionEvent`]
/// and updated by [`gamepad_event_processing_system`]. /// and updated by [`gamepad_event_processing_system`].
@ -325,11 +325,11 @@ pub enum ButtonSettingsError {
/// for (name, gamepad) in &gamepads { /// for (name, gamepad) in &gamepads {
/// println!("{name}"); /// println!("{name}");
/// ///
/// if gamepad.digital.just_pressed(GamepadButton::North) { /// if gamepad.just_pressed(GamepadButton::North) {
/// println!("{name} just pressed North") /// println!("{} just pressed North", name)
/// } /// }
/// ///
/// if let Some(left_stick_x) = gamepad.analog.get(GamepadAxis::LeftStickX) { /// if let Some(left_stick_x) = gamepad.get(GamepadAxis::LeftStickX) {
/// println!("left stick X: {}", left_stick_x) /// println!("left stick X: {}", left_stick_x)
/// } /// }
/// } /// }
@ -340,46 +340,175 @@ pub enum ButtonSettingsError {
#[require(GamepadSettings)] #[require(GamepadSettings)]
pub struct Gamepad { pub struct Gamepad {
/// The USB vendor ID as assigned by the USB-IF, if available. /// The USB vendor ID as assigned by the USB-IF, if available.
pub vendor_id: Option<u16>, pub(crate) vendor_id: Option<u16>,
/// The USB product ID as assigned by the [vendor], if available. /// The USB product ID as assigned by the [vendor], if available.
/// ///
/// [vendor]: Self::vendor_id /// [vendor]: Self::vendor_id
pub product_id: Option<u16>, pub(crate) product_id: Option<u16>,
/// [`ButtonInput`] of [`GamepadButton`] representing their digital state /// [`ButtonInput`] of [`GamepadButton`] representing their digital state
pub digital: ButtonInput<GamepadButton>, pub(crate) digital: ButtonInput<GamepadButton>,
/// [`Axis`] of [`GamepadButton`] representing their analog state. /// [`Axis`] of [`GamepadButton`] representing their analog state.
pub analog: Axis<GamepadInput>, pub(crate) analog: Axis<GamepadInput>,
} }
impl Gamepad { impl Gamepad {
/// Returns the USB vendor ID as assigned by the USB-IF, if available.
pub fn vendor_id(&self) -> Option<u16> {
self.vendor_id
}
/// Returns the USB product ID as assigned by the [vendor], if available.
///
/// [vendor]: Self::vendor_id
pub fn product_id(&self) -> Option<u16> {
self.product_id
}
/// Returns the analog data of the provided [`GamepadAxis`] or [`GamepadButton`].
///
/// This will be clamped between [[`Axis::MIN`],[`Axis::MAX`]].
pub fn get(&self, input: impl Into<GamepadInput>) -> Option<f32> {
self.analog.get(input.into())
}
/// Returns the unclamped analog data of the provided [`GamepadAxis`] or [`GamepadButton`].
///
/// This value may be outside the [`Axis::MIN`] and [`Axis::MAX`] range.
pub fn get_unclamped(&self, input: impl Into<GamepadInput>) -> Option<f32> {
self.analog.get_unclamped(input.into())
}
/// Returns the left stick as a [`Vec2`] /// Returns the left stick as a [`Vec2`]
pub fn left_stick(&self) -> Vec2 { pub fn left_stick(&self) -> Vec2 {
Vec2 { Vec2 {
x: self.analog.get(GamepadAxis::LeftStickX).unwrap_or(0.0), x: self.get(GamepadAxis::LeftStickX).unwrap_or(0.0),
y: self.analog.get(GamepadAxis::LeftStickY).unwrap_or(0.0), y: self.get(GamepadAxis::LeftStickY).unwrap_or(0.0),
} }
} }
/// Returns the right stick as a [`Vec2`] /// Returns the right stick as a [`Vec2`]
pub fn right_stick(&self) -> Vec2 { pub fn right_stick(&self) -> Vec2 {
Vec2 { Vec2 {
x: self.analog.get(GamepadAxis::RightStickX).unwrap_or(0.0), x: self.get(GamepadAxis::RightStickX).unwrap_or(0.0),
y: self.analog.get(GamepadAxis::RightStickY).unwrap_or(0.0), y: self.get(GamepadAxis::RightStickY).unwrap_or(0.0),
} }
} }
/// Returns the directional pad as a [`Vec2`] /// Returns the directional pad as a [`Vec2`]
pub fn dpad(&self) -> Vec2 { pub fn dpad(&self) -> Vec2 {
Vec2 { Vec2 {
x: self.analog.get(GamepadButton::DPadRight).unwrap_or(0.0) x: self.get(GamepadButton::DPadRight).unwrap_or(0.0)
- self.analog.get(GamepadButton::DPadLeft).unwrap_or(0.0), - self.get(GamepadButton::DPadLeft).unwrap_or(0.0),
y: self.analog.get(GamepadButton::DPadUp).unwrap_or(0.0) y: self.get(GamepadButton::DPadUp).unwrap_or(0.0)
- self.analog.get(GamepadButton::DPadDown).unwrap_or(0.0), - self.get(GamepadButton::DPadDown).unwrap_or(0.0),
} }
} }
/// Returns `true` if the [`GamepadButton`] has been pressed.
pub fn pressed(&self, button_type: GamepadButton) -> bool {
self.digital.pressed(button_type)
}
/// Returns `true` if any item in the [`GamepadButton`] iterator has been pressed.
pub fn any_pressed(&self, button_inputs: impl IntoIterator<Item = GamepadButton>) -> bool {
self.digital.any_pressed(button_inputs)
}
/// Returns `true` if all items in the [`GamepadButton`] iterator have been pressed.
pub fn all_pressed(&self, button_inputs: impl IntoIterator<Item = GamepadButton>) -> bool {
self.digital.all_pressed(button_inputs)
}
/// Returns `true` if the [`GamepadButton`] has been pressed during the current frame.
///
/// Note: This function does not imply information regarding the current state of [`ButtonInput::pressed`] or [`ButtonInput::just_released`].
pub fn just_pressed(&self, button_type: GamepadButton) -> bool {
self.digital.just_pressed(button_type)
}
/// Returns `true` if any item in the [`GamepadButton`] iterator has been pressed during the current frame.
pub fn any_just_pressed(&self, button_inputs: impl IntoIterator<Item = GamepadButton>) -> bool {
self.digital.any_just_pressed(button_inputs)
}
/// Returns `true` if all items in the [`GamepadButton`] iterator have been just pressed.
pub fn all_just_pressed(&self, button_inputs: impl IntoIterator<Item = GamepadButton>) -> bool {
self.digital.all_just_pressed(button_inputs)
}
/// Returns `true` if the [`GamepadButton`] has been released during the current frame.
///
/// Note: This function does not imply information regarding the current state of [`ButtonInput::pressed`] or [`ButtonInput::just_pressed`].
pub fn just_released(&self, button_type: GamepadButton) -> bool {
self.digital.just_released(button_type)
}
/// Returns `true` if any item in the [`GamepadButton`] iterator has just been released.
pub fn any_just_released(
&self,
button_inputs: impl IntoIterator<Item = GamepadButton>,
) -> bool {
self.digital.any_just_released(button_inputs)
}
/// Returns `true` if all items in the [`GamepadButton`] iterator have just been released.
pub fn all_just_released(
&self,
button_inputs: impl IntoIterator<Item = GamepadButton>,
) -> bool {
self.digital.all_just_released(button_inputs)
}
/// Returns an iterator over all digital [button]s that are pressed.
///
/// [button]: GamepadButton
pub fn get_pressed(&self) -> impl Iterator<Item = &GamepadButton> {
self.digital.get_pressed()
}
/// Returns an iterator over all digital [button]s that were just pressed.
///
/// [button]: GamepadButton
pub fn get_just_pressed(&self) -> impl Iterator<Item = &GamepadButton> {
self.digital.get_just_pressed()
}
/// Returns an iterator over all digital [button]s that were just released.
///
/// [button]: GamepadButton
pub fn get_just_released(&self) -> impl Iterator<Item = &GamepadButton> {
self.digital.get_just_released()
}
/// Returns an iterator over all analog [axes].
///
/// [axes]: GamepadInput
pub fn get_analog_axes(&self) -> impl Iterator<Item = &GamepadInput> {
self.analog.all_axes()
}
/// [`ButtonInput`] of [`GamepadButton`] representing their digital state
pub fn digital(&self) -> &ButtonInput<GamepadButton> {
&self.digital
}
/// Mutable [`ButtonInput`] of [`GamepadButton`] representing their digital state. Useful for mocking inputs.
pub fn digital_mut(&mut self) -> &mut ButtonInput<GamepadButton> {
&mut self.digital
}
/// [`Axis`] of [`GamepadButton`] representing their analog state.
pub fn analog(&self) -> &Axis<GamepadInput> {
&self.analog
}
/// Mutable [`Axis`] of [`GamepadButton`] representing their analog state. Useful for mocking inputs.
pub fn analog_mut(&mut self) -> &mut Axis<GamepadInput> {
&mut self.analog
}
} }
impl Default for Gamepad { impl Default for Gamepad {
@ -1307,7 +1436,7 @@ pub fn gamepad_event_processing_system(
}; };
let Some(filtered_value) = gamepad_settings let Some(filtered_value) = gamepad_settings
.get_axis_settings(axis) .get_axis_settings(axis)
.filter(value, gamepad_axis.analog.get(axis)) .filter(value, gamepad_axis.get(axis))
else { else {
continue; continue;
}; };
@ -1328,7 +1457,7 @@ pub fn gamepad_event_processing_system(
}; };
let Some(filtered_value) = settings let Some(filtered_value) = settings
.get_button_axis_settings(button) .get_button_axis_settings(button)
.filter(value, gamepad_buttons.analog.get(button)) .filter(value, gamepad_buttons.get(button))
else { else {
continue; continue;
}; };
@ -1337,7 +1466,7 @@ pub fn gamepad_event_processing_system(
if button_settings.is_released(filtered_value) { if button_settings.is_released(filtered_value) {
// Check if button was previously pressed // Check if button was previously pressed
if gamepad_buttons.digital.pressed(button) { if gamepad_buttons.pressed(button) {
processed_digital_events.send(GamepadButtonStateChangedEvent::new( processed_digital_events.send(GamepadButtonStateChangedEvent::new(
gamepad, gamepad,
button, button,
@ -1349,7 +1478,7 @@ pub fn gamepad_event_processing_system(
gamepad_buttons.digital.release(button); gamepad_buttons.digital.release(button);
} else if button_settings.is_pressed(filtered_value) { } else if button_settings.is_pressed(filtered_value) {
// Check if button was previously not pressed // Check if button was previously not pressed
if !gamepad_buttons.digital.pressed(button) { if !gamepad_buttons.pressed(button) {
processed_digital_events.send(GamepadButtonStateChangedEvent::new( processed_digital_events.send(GamepadButtonStateChangedEvent::new(
gamepad, gamepad,
button, button,
@ -2403,8 +2532,13 @@ mod tests {
assert_eq!(event.button, GamepadButton::DPadDown); assert_eq!(event.button, GamepadButton::DPadDown);
assert_eq!(event.state, ButtonState::Pressed); assert_eq!(event.state, ButtonState::Pressed);
} }
let gamepad = ctx.app.world_mut().get::<Gamepad>(entity).unwrap(); assert!(ctx
assert!(gamepad.digital.pressed(GamepadButton::DPadDown)); .app
.world_mut()
.query::<&Gamepad>()
.get(ctx.app.world(), entity)
.unwrap()
.pressed(GamepadButton::DPadDown));
ctx.app ctx.app
.world_mut() .world_mut()
@ -2419,8 +2553,13 @@ mod tests {
.len(), .len(),
0 0
); );
let gamepad = ctx.app.world_mut().get::<Gamepad>(entity).unwrap(); assert!(ctx
assert!(gamepad.digital.pressed(GamepadButton::DPadDown)); .app
.world_mut()
.query::<&Gamepad>()
.get(ctx.app.world(), entity)
.unwrap()
.pressed(GamepadButton::DPadDown));
} }
#[test] #[test]
@ -2439,13 +2578,23 @@ mod tests {
ctx.update(); ctx.update();
// Check it is flagged for this frame // Check it is flagged for this frame
let gamepad = ctx.app.world_mut().get::<Gamepad>(entity).unwrap(); assert!(ctx
assert!(gamepad.digital.just_pressed(GamepadButton::DPadDown)); .app
.world_mut()
.query::<&Gamepad>()
.get(ctx.app.world(), entity)
.unwrap()
.just_pressed(GamepadButton::DPadDown));
ctx.update(); ctx.update();
//Check it clears next frame //Check it clears next frame
let gamepad = ctx.app.world_mut().get::<Gamepad>(entity).unwrap(); assert!(!ctx
assert!(!gamepad.digital.just_pressed(GamepadButton::DPadDown)); .app
.world_mut()
.query::<&Gamepad>()
.get(ctx.app.world(), entity)
.unwrap()
.just_pressed(GamepadButton::DPadDown));
} }
#[test] #[test]
fn gamepad_buttons_released() { fn gamepad_buttons_released() {
@ -2488,8 +2637,13 @@ mod tests {
assert_eq!(event.button, GamepadButton::DPadDown); assert_eq!(event.button, GamepadButton::DPadDown);
assert_eq!(event.state, ButtonState::Released); assert_eq!(event.state, ButtonState::Released);
} }
let gamepad = ctx.app.world_mut().get::<Gamepad>(entity).unwrap(); assert!(!ctx
assert!(!gamepad.digital.pressed(GamepadButton::DPadDown)); .app
.world_mut()
.query::<&Gamepad>()
.get(ctx.app.world(), entity)
.unwrap()
.pressed(GamepadButton::DPadDown));
ctx.app ctx.app
.world_mut() .world_mut()
.resource_mut::<Events<GamepadButtonStateChangedEvent>>() .resource_mut::<Events<GamepadButtonStateChangedEvent>>()
@ -2528,13 +2682,23 @@ mod tests {
ctx.update(); ctx.update();
// Check it is flagged for this frame // Check it is flagged for this frame
let gamepad = ctx.app.world_mut().get::<Gamepad>(entity).unwrap(); assert!(ctx
assert!(gamepad.digital.just_released(GamepadButton::DPadDown)); .app
.world_mut()
.query::<&Gamepad>()
.get(ctx.app.world(), entity)
.unwrap()
.just_released(GamepadButton::DPadDown));
ctx.update(); ctx.update();
// Check it clears next frame //Check it clears next frame
let gamepad = ctx.app.world_mut().get::<Gamepad>(entity).unwrap(); assert!(!ctx
assert!(!gamepad.digital.just_released(GamepadButton::DPadDown)); .app
.world_mut()
.query::<&Gamepad>()
.get(ctx.app.world(), entity)
.unwrap()
.just_released(GamepadButton::DPadDown));
} }
#[test] #[test]

View file

@ -289,6 +289,28 @@ pub struct TextFont {
} }
impl TextFont { impl TextFont {
/// Returns a new [`TextFont`] with the specified font face handle.
pub fn from_font(font: Handle<Font>) -> Self {
Self::default().with_font(font)
}
/// Returns a new [`TextFont`] with the specified font size.
pub fn from_font_size(font_size: f32) -> Self {
Self::default().with_font_size(font_size)
}
/// Returns this [`TextFont`] with the specified font face handle.
pub fn with_font(mut self, font: Handle<Font>) -> Self {
self.font = font;
self
}
/// Returns this [`TextFont`] with the specified font size.
pub const fn with_font_size(mut self, font_size: f32) -> Self {
self.font_size = font_size;
self
}
/// Returns this [`TextFont`] with the specified [`FontSmoothing`]. /// Returns this [`TextFont`] with the specified [`FontSmoothing`].
pub const fn with_font_smoothing(mut self, font_smoothing: FontSmoothing) -> Self { pub const fn with_font_smoothing(mut self, font_smoothing: FontSmoothing) -> Self {
self.font_smoothing = font_smoothing; self.font_smoothing = font_smoothing;

View file

@ -1,3 +1,5 @@
//! Box shadows rendering
use core::{hash::Hash, ops::Range}; use core::{hash::Hash, ops::Range};
use crate::{ use crate::{
@ -133,14 +135,14 @@ impl FromWorld for BoxShadowPipeline {
} }
#[derive(Clone, Copy, Hash, PartialEq, Eq)] #[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub struct UiTextureSlicePipelineKey { pub struct BoxShadowPipelineKey {
pub hdr: bool, pub hdr: bool,
/// Number of samples, a higher value results in better quality shadows. /// Number of samples, a higher value results in better quality shadows.
pub samples: u32, pub samples: u32,
} }
impl SpecializedRenderPipeline for BoxShadowPipeline { impl SpecializedRenderPipeline for BoxShadowPipeline {
type Key = UiTextureSlicePipelineKey; type Key = BoxShadowPipelineKey;
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor { fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
let vertex_layout = VertexBufferLayout::from_vertex_formats( let vertex_layout = VertexBufferLayout::from_vertex_formats(
@ -333,8 +335,8 @@ pub fn extract_shadows(
} }
pub fn queue_shadows( pub fn queue_shadows(
extracted_ui_slicers: ResMut<ExtractedBoxShadows>, extracted_box_shadows: ResMut<ExtractedBoxShadows>,
ui_slicer_pipeline: Res<BoxShadowPipeline>, box_shadow_pipeline: Res<BoxShadowPipeline>,
mut pipelines: ResMut<SpecializedRenderPipelines<BoxShadowPipeline>>, mut pipelines: ResMut<SpecializedRenderPipelines<BoxShadowPipeline>>,
mut transparent_render_phases: ResMut<ViewSortedRenderPhases<TransparentUi>>, mut transparent_render_phases: ResMut<ViewSortedRenderPhases<TransparentUi>>,
mut views: Query<(Entity, &ExtractedView, Option<&UiBoxShadowSamples>)>, mut views: Query<(Entity, &ExtractedView, Option<&UiBoxShadowSamples>)>,
@ -342,7 +344,7 @@ pub fn queue_shadows(
draw_functions: Res<DrawFunctions<TransparentUi>>, draw_functions: Res<DrawFunctions<TransparentUi>>,
) { ) {
let draw_function = draw_functions.read().id::<DrawBoxShadows>(); let draw_function = draw_functions.read().id::<DrawBoxShadows>();
for (entity, extracted_shadow) in extracted_ui_slicers.box_shadows.iter() { for (entity, extracted_shadow) in extracted_box_shadows.box_shadows.iter() {
let Ok((view_entity, view, shadow_samples)) = views.get_mut(extracted_shadow.camera_entity) let Ok((view_entity, view, shadow_samples)) = views.get_mut(extracted_shadow.camera_entity)
else { else {
continue; continue;
@ -354,8 +356,8 @@ pub fn queue_shadows(
let pipeline = pipelines.specialize( let pipeline = pipelines.specialize(
&pipeline_cache, &pipeline_cache,
&ui_slicer_pipeline, &box_shadow_pipeline,
UiTextureSlicePipelineKey { BoxShadowPipelineKey {
hdr: view.hdr, hdr: view.hdr,
samples: shadow_samples.copied().unwrap_or_default().0, samples: shadow_samples.copied().unwrap_or_default().0,
}, },
@ -384,7 +386,7 @@ pub fn prepare_shadows(
mut ui_meta: ResMut<BoxShadowMeta>, mut ui_meta: ResMut<BoxShadowMeta>,
mut extracted_shadows: ResMut<ExtractedBoxShadows>, mut extracted_shadows: ResMut<ExtractedBoxShadows>,
view_uniforms: Res<ViewUniforms>, view_uniforms: Res<ViewUniforms>,
texture_slicer_pipeline: Res<BoxShadowPipeline>, box_shadow_pipeline: Res<BoxShadowPipeline>,
mut phases: ResMut<ViewSortedRenderPhases<TransparentUi>>, mut phases: ResMut<ViewSortedRenderPhases<TransparentUi>>,
mut previous_len: Local<usize>, mut previous_len: Local<usize>,
) { ) {
@ -394,8 +396,8 @@ pub fn prepare_shadows(
ui_meta.vertices.clear(); ui_meta.vertices.clear();
ui_meta.indices.clear(); ui_meta.indices.clear();
ui_meta.view_bind_group = Some(render_device.create_bind_group( ui_meta.view_bind_group = Some(render_device.create_bind_group(
"ui_texture_slice_view_bind_group", "box_shadow_view_bind_group",
&texture_slicer_pipeline.view_layout, &box_shadow_pipeline.view_layout,
&BindGroupEntries::single(view_binding), &BindGroupEntries::single(view_binding),
)); ));

View file

@ -11,18 +11,18 @@ fn main() {
fn gamepad_system(gamepads: Query<(Entity, &Gamepad)>) { fn gamepad_system(gamepads: Query<(Entity, &Gamepad)>) {
for (entity, gamepad) in &gamepads { for (entity, gamepad) in &gamepads {
if gamepad.digital.just_pressed(GamepadButton::South) { if gamepad.just_pressed(GamepadButton::South) {
info!("{:?} just pressed South", entity); info!("{:?} just pressed South", entity);
} else if gamepad.digital.just_released(GamepadButton::South) { } else if gamepad.just_released(GamepadButton::South) {
info!("{:?} just released South", entity); info!("{:?} just released South", entity);
} }
let right_trigger = gamepad.analog.get(GamepadButton::RightTrigger2).unwrap(); let right_trigger = gamepad.get(GamepadButton::RightTrigger2).unwrap();
if right_trigger.abs() > 0.01 { if right_trigger.abs() > 0.01 {
info!("{:?} RightTrigger2 value is {}", entity, right_trigger); info!("{:?} RightTrigger2 value is {}", entity, right_trigger);
} }
let left_stick_x = gamepad.analog.get(GamepadAxis::LeftStickX).unwrap(); let left_stick_x = gamepad.get(GamepadAxis::LeftStickX).unwrap();
if left_stick_x.abs() > 0.01 { if left_stick_x.abs() > 0.01 {
info!("{:?} LeftStickX value is {}", entity, left_stick_x); info!("{:?} LeftStickX value is {}", entity, left_stick_x);
} }

View file

@ -19,7 +19,7 @@ fn gamepad_system(
mut rumble_requests: EventWriter<GamepadRumbleRequest>, mut rumble_requests: EventWriter<GamepadRumbleRequest>,
) { ) {
for (entity, gamepad) in &gamepads { for (entity, gamepad) in &gamepads {
if gamepad.digital.just_pressed(GamepadButton::North) { if gamepad.just_pressed(GamepadButton::North) {
info!( info!(
"North face button: strong (low-frequency) with low intensity for rumble for 5 seconds. Press multiple times to increase intensity." "North face button: strong (low-frequency) with low intensity for rumble for 5 seconds. Press multiple times to increase intensity."
); );
@ -30,7 +30,7 @@ fn gamepad_system(
}); });
} }
if gamepad.digital.just_pressed(GamepadButton::East) { if gamepad.just_pressed(GamepadButton::East) {
info!("East face button: maximum rumble on both motors for 5 seconds"); info!("East face button: maximum rumble on both motors for 5 seconds");
rumble_requests.send(GamepadRumbleRequest::Add { rumble_requests.send(GamepadRumbleRequest::Add {
gamepad: entity, gamepad: entity,
@ -39,7 +39,7 @@ fn gamepad_system(
}); });
} }
if gamepad.digital.just_pressed(GamepadButton::South) { if gamepad.just_pressed(GamepadButton::South) {
info!("South face button: low-intensity rumble on the weak motor for 0.5 seconds"); info!("South face button: low-intensity rumble on the weak motor for 0.5 seconds");
rumble_requests.send(GamepadRumbleRequest::Add { rumble_requests.send(GamepadRumbleRequest::Add {
gamepad: entity, gamepad: entity,
@ -48,7 +48,7 @@ fn gamepad_system(
}); });
} }
if gamepad.digital.just_pressed(GamepadButton::West) { if gamepad.just_pressed(GamepadButton::West) {
info!("West face button: custom rumble intensity for 5 second"); info!("West face button: custom rumble intensity for 5 second");
rumble_requests.send(GamepadRumbleRequest::Add { rumble_requests.send(GamepadRumbleRequest::Add {
gamepad: entity, gamepad: entity,
@ -62,7 +62,7 @@ fn gamepad_system(
}); });
} }
if gamepad.digital.just_pressed(GamepadButton::Start) { if gamepad.just_pressed(GamepadButton::Start) {
info!("Start button: Interrupt the current rumble"); info!("Start button: Interrupt the current rumble");
rumble_requests.send(GamepadRumbleRequest::Stop { gamepad: entity }); rumble_requests.send(GamepadRumbleRequest::Stop { gamepad: entity });
} }

View file

@ -395,10 +395,10 @@ fn update_buttons(
) { ) {
for gamepad in &gamepads { for gamepad in &gamepads {
for (mut handle, react_to) in query.iter_mut() { for (mut handle, react_to) in query.iter_mut() {
if gamepad.digital.just_pressed(**react_to) { if gamepad.just_pressed(**react_to) {
*handle = materials.active.clone(); *handle = materials.active.clone();
} }
if gamepad.digital.just_released(**react_to) { if gamepad.just_released(**react_to) {
*handle = materials.normal.clone(); *handle = materials.normal.clone();
} }
} }