#bevy_mod_picking

3321 messages Β· Page 4 of 4 (latest)

fiery night
runic glade
#

oh yeah, mouse motion events seems to be what i'm looking for

wispy sierra
lament vapor
#

Hello, any advice about how I should use bevy_mod_picking to resize sprites/mesh2D dragging its edges ? I can't find any example showcasing this, but this crate seems like the perfect solution for that, right?

eternal pumice
#

If those gadget are only visible when the cursor is close that could get pretty sleek

lament vapor
#

Ohhh god idea! 🀩 thx!

runic glade
#

im having some trouble getting picking working with avian2d. ive added PickableBundle to the entity that i want to be able to select, DefaultPickingPlugins to my app, and also the "backend_avian" feature in my toml. i feel like theres something small im missing but i have no clue what it is

novel hamlet
#

there is only an avian 3d backend as far as I'm aware

runic glade
#

ah i see

#

making a 2d backend would probably just be as simple as checking for point intersections right

novel hamlet
#

I'm not familiar with avian, but I assume so, yes. It's likely you can copy past the 3d backend and only make small tweaks to get it working for 2d

runic glade
#

yup, for sure

#

and i assume i wouldn't use the raymap right? because that seems to be geared towards 3d raycasts

novel hamlet
#

Not sure, sorry! Sounds right though.

fiery night
#

Q: Can you think of a way to make raycasting conditional based on the game state? So for example in flora-painting mode trees are pickable, in terrain sculpting mode trees are not pickable but heightmaps are, etc.

granite oyster
novel hamlet
#

For raycasting specifically, you can add query filters to the raycast. Depends on the backend though.

prisma kernel
#

Hi, I'm new to picking (and bevy_ui tbh), but I'm a little confused about the behavior I'm seeing. I have a ButtonBundle (with the PickableBundle), and as a child I added a TextBundle (no Pickable). I want to highlight the button on hover and press, so I followed the many_buttons example and used the PickingInteraction component and switched to decide the color. However what I found is that when my cursor hovers the TextBundle, it doesn't highlight the button. I have some padding on my button, and hovering the padding does highlight the button, so it seems like the TextBundle is blocking the cursor even though it's not pickable.

Is this expected behavior? Do I need to add some sort of "ignore picking" component?

prisma kernel
#

I also have a press event on the button, and it is triggering correctly even when I click through the TextBundle, so perhaps this is a problem isolated to PickingInteraction?

prisma kernel
#

OK NEVERMIND I FOUND Pickable::IGNORE, NOW GO AHEAD AND IGNORE ME πŸ˜›

vernal token
granite oyster
prisma kernel
#

Yeah but that doesn't apply to the PickableInteraction. I could have probably worked around this by handling the particular events yeah

prisma kernel
#

For another question, how would I handle a click that doesn't hit any pickable objects? For example, I might have an RTS UI where I can pick which building to place, but if clicking into the game world I want to trigger my own building placement code or something

#

I did find the implementation of bevy_picking_selection which seems to do this, but requires iterating through three different press events to figure out which presses have been handled πŸ˜›

novel hamlet
prisma kernel
novel hamlet
#

I mean, if you want to pick it, then it should be pickable. πŸ˜„

prisma kernel
#

The weird part is I'm not trying to pick the background in particular (e.g., if there are multiple entities that compose the background). I just want to know if I missed everything I care about so I can run my custom code

#

Maybe then I should be marking my background with a Background component πŸ˜…

novel hamlet
#

if clicking into the game world I want to trigger my own building placement code
sounds like you are describing "when I drag a building and drop it on the background, run some code"

#

the Pointer<Drop> event seems like exactly what you would want here, it tells you the entity being dropped, and the entity it was dropped on.

prisma kernel
#

Not quite. If i'm playing an RTS, I don't want to drag my structure icon and then drop it into the world. I usually want to click the ui once to select which building to place (or press a hotkey), and then click again in the game world once I've placed the "ghost" structure properly

novel hamlet
#

Ah, gotcha. Then it seems like you want to be able to click the game world, and track what building is currently selected. Either way, seems like you want the world/map to be pickable.

prisma kernel
#

I agree for 3D games, I think that makes sense there. But for 2D, I think this makes less sense? Like if it's a side scroller like Terraria, It doesn't make as much sense to me to say the parallax background is pickable, and the tiles are pickable and anything else in the background is pickable. I'd rather just have them all be non-pickable, detect that and then do my "tile math" or whatever to figure out what tile to place or break or whatever

#

I hope this isn't coming across too negative, I am interested to understand how you approach this since I'm new to picking πŸ˜…

novel hamlet
#

If you want to interact with this stuff with a pointer, why wouldn't you want it to be pickable? Pickable doesn't mean it highlights, selects, takes focus, etc, etc, it just means you get events with pointers.

detect that and then do my "tile math"
That just sounds like hand rolling your own picking thing. πŸ˜›

prisma kernel
#

I think the thing that bothers me with the pickable component approach is that I have to remember to put it on everything even if I don't care to interact with that particular object. I never want to interact with parallax backgrounds, but if I want to use this approach, I need to add it there just so Pointer events are sent (which I can then filter through an EventReader).

#

As for the "tile math" thing, my concrete example is I have an object that is say 2x2 tiles wide. I want the cursor to be "rounded" to tiles, not floored. So picking a particular tile would not be desirable, since that would make the placed object be "skewed" relative to where the mouse is.

#

Unless I just do the "tile math" inside the pointer event handler, but then the actual entity I picked isn't relevant.

novel hamlet
novel hamlet
#

But for 2D, I think this makes less sense
It's the same logic that is used for interacting with 2D UI. E.g. "if the user clicks on this 2D surface, run a system". You don't just want to know what coordinates the user clicked on, you want to know that the click wasn't blocked by something in front of it.

olive hull
#

Hi! I have some ImageBundles that I'd like to drag, but they have transparency. My solution was returning in the On<Pointer<Drag> callback before changing the position of the ImageBundle, but this doesn't actually stop the drag event, so if the mouse moves over a non-transparent part, the ImageBundle is dragged without a new event

#

Recording a video to show

novel hamlet
#

The backend needs to be updated to support transparency.

#

This would be in the sprite picking backend iirc

granite oyster
olive hull
novel hamlet
#

In that case, yes, it would need to be added in the bevy_ui backend.

olive hull
#

Got it, thanks

heady tapir
#

hey! i use EventReader<MouseWheel> to zoom in my game. is there an easy way i can use mod_picking for the mouse wheel so that when im interacting with a scrollarea the wheel events arent passed through?

buoyant escarp
#

Yes! You can look up which entity the cursor is hovering over using the HoverMap

heady tapir
#

that works ty!

buoyant escarp
#

Once input management is upstreamed this sort of interaction with the (newly upstreamed picking) will probably be pretty common and painless.

heady tapir
#

very excited for that :D

limpid cedar
#

I have an invisible parent entity with several PBR child entities. Currently I added PickableBundle on the parent entity. Now the child entities can be hovered, but no select event is fired on them. How to fix this?
hovering and clicking work just fine (the event gets fired for the child entity which has no PickableBundle, which is fine since I can just iter_ancestors)
but the select event never gets fired, no matter which entity I add the select hook on

lean quail
#

Hello. I'm trying to add the drag and drop functionality to some entities. I have the Avian backend. When I add On::<Pointer<DragStart>>::target_insert(Pickable::IGNORE) to the entity an error says that Pointer should be <dyn Pointer>. Adding dyn then says dyn isn't implemented.

I'm not sure what I'm doing differently than the drag_and_drop example. The example doesn't need dyn.

lean quail
#

update: I was importing std::fmt::pointer, not the picking pointer

#

this was an id10t error

limpid cedar
#

it sounds like a bug

#

I don't know how hierarchies are supposed to work with mod picking, but the inconsistent behavior between hovering and eslection sounds like a bug

buoyant escarp
#

I'm not sure I understand the issue.

limpid cedar
# buoyant escarp I'm not sure I understand the issue.

basically I have entities like this

parent = spawn((
  SpatialBundle,
  PickableBundle,
  On(Pointer<Over>), On(Pointer<Out>),
  On(Pointer<Select>), On(Pointer<Deselect>),
))
child = parent.with_children(|b| b.spawn((
  PbrBundle,
)))

when I hover over the child, the parent receives the Over event, but when I click, it doesn't receive the Select event

sudden panther
#

How can I make clicks pass through?

I'm developing a building system where I move objects based on a tilemap. The issue is that the building preview is a 2D sprite, which interferes with hovering over the tiles behind the sprite. For example, if I have a large building that occupies a 3x3 area, and I want to move it by one tile, I can't do that because the tile is obscured by the sprite

#

On::<Pointer<Over>>::run(
    move |_: Listener<Pointer<Over>>,
          mut preview_query: Query<(&mut Transform, &PreviewBuilding)>,
          tilemap_query: Query<(
        &TilemapGridSize,
        &TilemapType,
        &GlobalTransform,
    )>| {
        let (grid_size, map_type, tilemap_transform) = tilemap_query.single();
        let world_pos = tile_pos.center_in_world(grid_size, map_type);

        if let Ok((mut preview_transform, preview_building)) =
            preview_query.get_single_mut()
        {
            preview_transform.translation = tilemap_transform
                .transform_point(world_pos.extend(10.0))
                + preview_building.offset.extend(0.0);
        }
    },
),

granite oyster
thick sparrow
#

Is there a supported way to pick quadrilaterals (or a collection of intersecting lines) better than manually defining a TriangleList mesh made up of multiple triangles?

prisma kernel
#

If I have a drag listener and I want to drag an object, what's the correct way to do that? Using the examples in the repo, I'm running into issues, since I allow zooming my camera. When I zoom the camera, the delta field no longer corresponds to world units.

#

This seems to be a limitation of the ListenerInput or Pointer events. They don't expose the camera that produced the hit.

#

As a workaround I can just look up my one camera, but in a multi-camera set up, that would not work

forest ledge
#

I'm getting Ord violation panics at this line: https://github.com/aevyrie/bevy_mod_picking/blob/74f0c3c0fbc8048632ba46fd8f14e26aaea9c76c/backends/bevy_picking_sprite/src/lib.rs#L56-L61

I confirmed that it's because z is NaN and smallsort expects the comparison operator to be correct:

// We now should have consumed the full input exactly once. This can
// only fail if the comparison operator fails to be Ord, in which case
// we will panic and never access the inconsistent state in dst.
if left != left_end || right != right_end {
    panic_on_ord_violation();
}

I'm surprised that Bevy lets me make a transform which is invalid in the first place, but nevertheless, is this something that should be fixed in bevy_picking_sprite to avoid comparing NaNs, or should this panic as it does and leave it up to callers to make sure they never set invalid transforms? I note that this has been upstreamed so would need to be fixed there actually: https://github.com/bevyengine/bevy/blob/b45d83ebda8f4956f59fa30cc6f03f5c11fc494f/crates/bevy_sprite/src/picking_backend.rs#L46-L51

marble pine
hasty sail
#

Getting an ordering issue due to bubbling πŸ˜•
So let's say there's an entity like this:

On::<Pointer<Over>>::run(/* set special bg color */),
On::<Pointer<Out>>::run(/* reset to default bg color */),

And let's say the entity contains children.

  1. Hover over a child.
  2. Event bubbles from child, triggering Pointer<Over>
  3. Move cursor over to the parent, away from the child
  4. Event bubbles from child, triggering Pointer<Out>
  5. Pointer<Over> is triggered on parent

The issue here is that step 4 and 5 is not deterministic. If they are ordered like above, it works fine. But sometimes step 5 is triggered before step 4, causing the bg color to stay reset.
I guess it's kinda futile to mull over this since the bubbling mechanism is already replaced by an upstream solution. But I wonder if the upstream version suffers from the same issue.

buoyant escarp
#

It does, I think. But this can be fixed.

#

Or… actually

#

Over always precedes out now, within a single frame.

#

I’ll have to take a sec to look into this more. If you get the events on the same frame it will always be Over-parent then Out-child. If you get them across two frames (which could happen because we do a 2-frame diff for these events) then it will always be Out-child then next frame then Over-Parent.

#

Either way it should be deterministic in bevy_picking

hasty sail
buoyant escarp
#

when i wrote the ordering, I fired over first and out last, and put all the other events between. The reason for this is that you do want to receive Over before stuff like DragStart, and you do want to receive stuff like DragDrop before Out.

#

Because of how mod_picking works, we don't actually know when the transition between picked entities happens relative to the other events, so we just kind of have to pick something that makes sense.

#

Within a single frame, we can't have out precede over unless we want to break another case. Which is why I am sort of hoping that multi-frame stuff can sort this out.

#

I don't think it does though.

buoyant escarp
granite oyster
#

I've got what I think is an ordering ambiguity: #1034547742262951966 message Basically I think lwim is resetting action states immediately after mod_picking is setting them. I don't know exactly which system set to order after lwim... I was thinking I could just do all of them, but that seems wasteful

#

Is there a specific set I could order lwim's action resetting against to make sure the handler gets called after? My first thought was EventListenerSet

wise fiber
#

Hello, I was wondering if anyone could help me with this (I'm kind of new to rust, bevy and bevy_mod_picking).
I'm trying to spawn a grid of cubes and whenever you click on a cube a bevy event gets sent containing the position of said cube. I'm not sure if this is the most correct or efficient way of doing it, so any advice would be really appreciated.
Here is my (not working) code so far:

level.pos_iter().for_each(|(pos, _tile)| {
            println!("New tile at: {} {}", pos.x, pos.y);
            commands.spawn(
                (
                    PbrBundle {
                        transform: Transform::from_translation(Vec3::new(pos.x as f32, 0.0, pos.y as f32)),
                        mesh: meshes.add(Cuboid::new(0.9, 0.9, 0.9)),
                        material: materials.add(Color::srgb(1.0, 0.0, 0.0)),
                        ..default()
                    },
                    On::<Pointer<Click>>::run(move || {
                        evw_handle_click.send(HandleClickEvent(pos));
                    })
                )
            );
        });

If you need any more info on the code please let me know!

granite oyster
#

What's not working about the code?

wise fiber
#

This works however I'm unable to pass the pos variable because it is outlived by the On:: call and I need to send said data with the event

novel hamlet
#

You probably want to be querying for the current position of the cube within the callback system, and send that in the event.

wise fiber
#

Thanks, that helped me get what I wanted!

#

One more question if you dont mind. How can I perform two actions with one event listener? In my case I have inserted th following components to an entity:

On::<Pointer<Click>>::commands_mut(|event, commands| {
    // Some code...
}),
On::<Pointer<Click>>::send_event::<HandleClickEvent>()

This produces an error saying that On::<Pointer<Click>> can't be duplicate.

novel hamlet
#

You would use On::run, and put all the logic in there

#

commands_mut and send_event are just sugar and use On::run under the hood

#

It's equivalent to having two systems and combining them into one

wise fiber
#

Got it to work, thanks for your time :D

still rover
#

is it possible to make middle/right mouse button not trigger interaction?

patent mortar
#

I can send an example later away from computer atm

still rover
#

I'm kinda micromanaging the Interaction component for specific interactions and I prefer not to use bevy_mod_picking's events

patent mortar
#
impl From<ListenerInput<Pointer<Down>>> for FleetClicked {
    fn from(value: ListenerInput<Pointer<Down>>) -> Self {
        FleetClicked {
            entity: value.listener(),
            button: value.button,
        }
    }
}```
#
#[derive(Event)]
pub struct FleetClicked {
    entity: Entity,
    button: PointerButton,
}

patent mortar
#
for event in fleet_events.read() {
        if event.button != PointerButton::Primary {
            continue;
        }
//And so on
}
still rover
#

Yeah events probably work but I really like working exclusively with PickingInteraction, since working with states is the better ECS pattern imo.

patent mortar
#

Fair enough I wouldn't know how to do it that way though

still rover
#

Anyway if I want to make a PR for this, do I do it on bevy_mod_picking or directly to the upstreaming process? Hasn't kept up with 0.15 development.

delicate marsh
#

hello, whats the "refresh rate" of pointer event for bevy ui ? i have a grid of square, and a pointer<dragover> but when i move diagonally is misses a lot of times a grid item it has dragged over because the mouse was only briefly in a corner of the adjacent tile.
thanks ! i can do a demo if my explanation isn't clear

granite oyster
novel hamlet
#

Can also use ```rs shorthand

native mountain
#

Heya!

I'm trying to use the drag events, but I noticed that while DragStart contains a HitData, the Drag and DragEnd events do not. While I'de love to use the HitData.position property while dragging, or at least have access to a worldspace ray, to determine where i'm dragging to in world space.

I could query for the right Camera that matches the pointer_location, and determine the ray again in my eventhandler system, but it seems like a dirty fix, as if i'm overlooking something.

what would be the best solution?

novel hamlet
#

There is no gaurantee that the pointer will be hitting the target after you start dragging. It means that the pointer was hitting an entity when a drag started.

#

The only information you have is the drag delta as the pointer moves after it starts dragging an entity

#

If you want to know a world space position, you can look to see if the pointer is hitting anything while it is dragging.

#

But you are also not gauranteed to be hitting anything.

native mountain
#

hmm alrighty, fair!

#

Thanks 😊

opaque garden
#

Is there a way to disable and enable pointers? I want to switch back and fourth between a virtual pointer (middle of the screen crosshairs) and the mouse pointer depending on the game state (i.e. UI vs in-game).

Or do I need to manually despawn and respawn the pointers?

novel hamlet
#

I don't fully understand the use case, but can you just swap the PointerId component out on the entity?

opaque garden
#

I have picking events with a virtual pointer while in-game using the rapier backend. And also UI picking using the built-in mouse PointerId so I have two separate pointers in this case.

#

So you suggest querying the the PointerId::Mouse component and removing it when I'm not in a UI state and want to ignore the normal mouse pointer? Would that cause issues since they are normally spawned automatically?

novel hamlet
#

You might need to customize that spawning logic. It sounds to me like you really just want a single pointer, but change whether it is driven by the mouse or locked to the center of the screen.

novel hamlet
opaque garden
#

Hmm I'm also "changing" the backend though. With the virtual pointer I only care about meshes and want to ignore any UI elements or HUD elements

novel hamlet
#

Might be a nice feature to add in the upstreamed version, being able to just disable a pointer's ability to interact seems handy.

#

Another option would be to customize the backends you are using to query for some pointer enable/disable component

opaque garden
#

I could also use require_markers and swap which elements are tagged on state change right?

novel hamlet
#

Sure

opaque garden
#

Hmm nevermind I guess Bevy UI doesn't have that feature, only rapier and raycast, etc.

#

Anyways thanks for the ideas! I'll poke around more tomorrow.

steel island
steel island
#

I expected some code where all these events are "fired()" at the right time.

novel hamlet
#

You have to expand the results

patent mortar
#

On::<Pointer<Down>>::target_commands_mut() is there a non mutable version I just want it for logging transfroms

novel hamlet
#

I'd check the docs. If not, it won't make a difference anyway. You can also use On::run

echo yew
#

How would one use bevy-inspector-egui combined with mod_picking, and have mod_picking not register an event when the mouse is over the inspector UI?

#

I can see the backend_egui feature, but that seems to do the opposite? But even if I don't enable that feature, a click in the inspector window still cascades down to whatever bevy UI element is below the inspector.

marble pine
novel hamlet
#

@marble pine this is why I want bevy_ui to explicitly be tied to a camera. Implicit ordering is a bit of a nightmare.

#

e.g. magically attaching the ui to a 3d camera makes no sense because you lose all control over where the UI is rendered, and you now have two entirely different behaviors depending entirely on how you happened to spawn your UI root.

#

It also makes the picking integration hacky. We add a 0.5 offset to the camera to make this function, but again, it's working around the UI being implicit (sometimes!)

#

Just give me a UiCamera and let me order it relative to every other camera.

marble pine
#

Worth trying but...

novel hamlet
#

I generally think all entities should have the same camera semantics. E.g. if you add a mesh with no 3d camera, well, nothing will render. Why should UI entities be any different? You don't see users complaining about DX because bevy doesn't auto-spawn a 3d camera when a mesh is present.

#

And we have a tool for picking what camera sees what entities: renderlayers

marble pine
#

#ui-dev?

novel hamlet
#

Changing the behavior across entities just makes learning harder, more concepts to do the same thing

#

I've already beat this drum and cart shot it down for DX reasons I disagree with. Not sure I can really do much tbh

echo yew
novel hamlet
#

At least, that should do it

fallen wharf
novel hamlet
#

Ah, you know

#

the issue is probably that your UI interaction code is not using the picking primitives, which do respect the layer stuff

#

You might also need to make sure bevy_ui's built in focus system isn't also running.

#

This should all work correctly in the next version of bevy, assuming the code for Interaction is using the new picking stuff

echo yew
novel hamlet
#

I was thinking you might be using Interaction, and bevy uis built in focus system is obliterating the mod picking stuff

#

I'd use the debug pointer to see what entities are hovered. Our should just be egui when over egui

echo yew
#

(doesn't matter if I enable backend_egui or not in this case)

fervent carbon
#

Hello, Im testing minimal_2d.rs, But I have no idea why it not work.

#

I'm using ldtkentity to spawn PickableBundle

#[derive(Copy, Clone, Eq, PartialEq, Debug, Default, Component)]
pub struct PlaceAble;

#[derive( Default, Bundle, LdtkEntity)]
pub struct PlaceAbleBundle {
    struct_id: PlaceAble,
    pickable: PickableBundle,
}
#

And insert event for it:

#[derive(Copy, Clone, Eq, PartialEq, Debug, Default, Component)]
pub struct PlaceAbleEvent;

fn add_events(mut commands: Commands, q_placeable_rntity: Query<Entity, Added<PlaceAble>>) {
    for e in &q_placeable_rntity {
        commands.entity(e).insert(
            On::<Pointer<Click>>::run(|| info!("I've been clicked!")),
        );
    }
}
#

The weird thing is that when my old hover function system is running, it works fine

#

My old system:

#[derive(Debug, Default)]
pub struct PlaceablePlugin;

impl Plugin for PlaceablePlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Update, ( hover_placeable, touch_placeable, add_events));
    }
}

fn hover_placeable(
    mut commands: Commands,
    q_window: Query<&Window, With<PrimaryWindow>>,
    q_camera: Query<(&Camera, &GlobalTransform), With<Camera2d>>,
    q_transform_placeable: Query<(Entity, &GlobalTransform), With<PlaceAble>>,
) {
    let (camera, camera_transform) = q_camera.single();
    let window = q_window.single();
    if let Some(world_position) = window
        .cursor_position()
        .and_then(|cursor| camera.viewport_to_world(camera_transform, cursor))
        .map(|ray| ray.origin.truncate())
    {
        for (entity, placeable_trans) in &q_transform_placeable {
            let distance = world_position.distance(placeable_trans.translation().xy());
            if distance < 32. {
                commands.entity(entity).insert(Hover);
            } else {
                commands.entity(entity).remove::<Hover>();
            }
        }
    }
}
#

It's Output:

2024-10-29T06:01:34.002674Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Windows 10 Pro", kernel: "19045", cpu: "Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz", core_count: "4", memory: "32.0 GiB" }
2024-10-29T06:01:34.456198Z  INFO bevy_render::renderer: AdapterInfo { name: "NVIDIA GeForce RTX 2070 SUPER", vendor: 4318, device: 7812, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "560.94", backend: Vulkan }
2024-10-29T06:01:35.262070Z  INFO bevy_winit::system: Creating new window "KautismTD" (Entity { index: 0, generation: 1 })
2024-10-29T06:01:38.278550Z  INFO tdrpg::placeable: I've been clicked!
2024-10-29T06:01:38.919977Z  INFO tdrpg::placeable: I've been clicked!
2024-10-29T06:01:40.240954Z  INFO bevy_window::system: No windows are open, exiting
2024-10-29T06:01:40.249371Z  INFO bevy_winit::system: Closing window Entity { index: 0, generation: 1 }
#

Because I planned to replace the old system with bevy_mod_picking, but it failed.

#

I remove old system:

- app.add_systems(Update, ( hover_placeable, touch_placeable, add_events));
+ app.add_systems(Update, ( touch_placeable, add_events));
#

I didn't even know what I did wrong.

fervent carbon
#

OK, I know. This entity do not contains sprite so mod_picking dont know how to click it.

#

Can i using avian2D as backend? I didn't see any example code for avian 2D, avian.rs seems is avian3d.

echo yew
#

@novel hamlet any way to temporarily disable all picking interactions?

If so, I could use Egui's wants_pointer_input to check if bevy-inspector-egui is being used, and disable any picking logic until it is needed again.

#

Ah, I found InputPluginSettings, looking into whether that's what I need

#

Yes, that worked. Here's the system I added to fix my issue. I'm sure it can be improved, possibly with a run condition.

// Disable picking when the inspector is active.
fn toggle_picking(
    mut ctx: Query<&mut bevy_inspector_egui::bevy_egui::EguiContext>,
    mut input: ResMut<bevy_mod_picking::prelude::InputPluginSettings>,
) {
    if ctx.single_mut().get_mut().wants_pointer_input() {
        input.is_touch_enabled = false;
        input.is_mouse_enabled = false;
    } else if !input.is_touch_enabled || !input.is_mouse_enabled {
        input.is_touch_enabled = true;
        input.is_mouse_enabled = true;
    }
}
novel hamlet
echo yew
#

Hmm, looking at that backend now, but it's using it in the other direction, right? E.g. it's using wants_pointer_input to actually register interactions inside egui windows?

#

I want/do the inverse: disable interactions when over an Egui window (since the interactions don't happen on the inspector window, but happen on the underlying bevy UI nodes).

echo yew
#

And for anyone interested, here's how to change the color of the debug text (when using bevy_ui):

fn update_picking_debug_color(mut pointers: Query<&mut Text, With<PointerDebug>>) {
    for mut text in &mut pointers {
        for section in &mut text.sections {
            if section.style.color == Color::WHITE {
                section.style.color = Color::BLACK;
            }
        }
    }
}
fervent carbon
#

When I insert hover (a class I created myself), I hope it has an animation, but since this animation is a child element, it seems that a large number of Over Events are triggered every time the animation is played.

#

Is there any to let the plugin to know which entity do not trigger by child?

fervent carbon
#

Ok, I know, i using worng function to do that. Shouldnt using target_insert, use listener_insert instead.

novel hamlet
#

You can see this working in the example

echo yew
#

@novel hamlet I see. So do you have any idea why, when enabling bevy_egui as a feature, it still registers hits for the bevy_ui elements below the egui window?

novel hamlet
opaque garden
#

@novel hamlet I'm having an issue where respawning UI in the Update schedule causes bevy_mod_picking to not run the callback system. I've tested this with a simple UI with a single buttton that gets respawned every frame and verified it will never trigger any callbacks.

This is surprising to me because from reading the code all the bevy_mod_picking systems happen in PreUpdate. Thus, if the user clicks it should only care about what exists at the current point on that frame and the fact that it is despawned later that frame shouldn't matter, right? I'm probably missing something as to why this breaks.

Here's the minimal system that reproduces this (running in Update):

fn render_system(mut commands: Commands, node_query: Query<Entity, With<Ui>>) {
    if let Ok(entity) = node_query.get_single() {
        commands.entity(entity).despawn_recursive();
    }
    commands
        .spawn(NodeBundle {
            // Root node with styles, etc.
        })
        .insert(Ui)
        .with_children(|children| {
            children
                .spawn(ButtonBundle {
                    // Button with basic style and background color.
                })
                .insert(On::<Pointer<Click>>::run(move || warn!("Hello world!")));
        });
}
opaque garden
#

I do see this comment on bevy_picking_egui (https://github.com/aevyrie/bevy_mod_picking/blob/74f0c3c0fbc8048632ba46fd8f14e26aaea9c76c/backends/bevy_picking_egui/src/lib.rs#L31) which is immediate mode API that seems to be a work around for a similiar issue. But I don't understand why that is needed -- if it runs in PreUpdate why doesn't it just detect hits for the UI spawned on the previous frame? It also isn't a solution for Bevy UI since the backend depends on ViewVisibility which is computed in PostUpdate (i.e. I can't just spawn immediate mode UI in PreUpdate).

novel hamlet
#

To be frank, I don't really have the wherewhithal to debug issues like this. All effort has gone into upstreaming this plugin to bevy, and switching from eventlisteners to bevy's observers. There have been a number of fixes and improvements made during the upstreaming, the existing plugins will be put on life support.

opaque garden
opaque garden
novel hamlet
#

Click and other events rely on the entity being the same. If you are respawning, the entity id will change

#

e.g. a click is a mouse down and a mouse up on the same entity

#

I suspect this would work for pointer down events though

opaque garden
#

Ohhh, snap. That's probably it. I was not remembering Click was down and up. I might just switch to pointer down then. Thank you!

opaque garden
novel hamlet
#

Not sure about that though

opaque garden
#

Gotcha, thanks again!

novel hamlet
#

Either way, most of that stuff has been revamped for the observers version in 0.15

vernal token
vernal token
delicate marsh
#

hey ! is there a way of having the DragOver event trigger even when the target is the dragged entity ? like dragging the entity on self (i want to know if the dragged entity passed through itself again, so reset a pathing)
thanks !

novel hamlet
#

You could check what is under the pointer during drag events maybe?

delicate marsh
# novel hamlet What do you mean by drag an entity onto itself?

like the mouse cursor which started the drag event while dragging goes back to the entity that first started being dragged. i dont move it, so its place remain fixed.
thanks for the idea and response ! ill do that with the HitData, but its more cumbersome

fervent carbon
#

Hello, why does my drop event not trigger correctly? It seems random, and I can't even figure out its regular pattern.

novel hamlet
#

it looks like the object you are dragging is also pickable, and is blocking from dropping things underneath

fervent carbon
#

I change this object to:
.insert(Pickable{
should_block_lower: false,
..Default::default()
})

#

Sometimes it trigger double drop event

#

I add a checker to prevent this but not work, it only blocks part of events

fn drop(
    mut commands: Commands,
    event: Listener<Pointer<Drop>>,
    bultinassets: Res<BultinAssets>,
) {
    info!("Drop");
    if event.dropped == event.target {
        info!("Skip Drop!");
        return;
    }
fervent carbon
#

It seems i move insert Pickable::IGNORE prevent this bug.

fervent carbon
#

It's my fault. I use wrong with<> in query.

river aspen
#

Hi guys, I've been playing with the example minimal_2d, but seems like it doesn't work.
Is the example outdated?

novel hamlet
#

Is this on main?

#

I think I broke 2d with a feature change

river aspen
#

I tried bring it to main as well, and it still doesn't work

prisma kernel
#

It looks like bevy_mod_picking doesn't have a PR for 0.15. Is this in the works, or should I take it up? I understand a lot of picking has been upstreamed, but many of the backends (including sprite backend) is still missing.

#

At the very least when 0.15 drops, there should be a migrations strategy, even if it's a hacky mid-way between the upstreamed stuff and the non-upstreamed code.

prisma kernel
#

Ah awesome! Thank you

novel hamlet
prisma kernel
#

Or maybe not publicly visible

marble pine
#

Can you double check then open an issue?

prisma kernel
#

It might not actually be necessary now that I think about it. If it's always added through the SpritePlugin, that is probably fine

novel hamlet
#

It's likely you are just on a more recent version than mod_picking supports

echo yew
#

Aha. Should Picking perhaps limit the versions of egui it supports? Or is this all moot now that picking is being upstreamed?

novel hamlet
#

If anything I need it to support multiple versions, which I have done in the past. Problem is that there have been breaking changes to egui that mean the code is not cross compatible

vernal token
#

@novel hamlet Hi, i woke up to some compiler issues this morning and looks like i got that sorted (had to clear cargo cache and disable cranelift). Since last night i have not changed any of the code, but picking events dont seem to be firing now. Can u give me a checklist list of things to look for? The events are being registered by the app. The Pickable and On<x> components are also there. I have a button that uses picking as well and it seems to be working fine, so its not app wide.

novel hamlet
#

that sounds like a version mismatch to me

#

cargo tree -i bevy_mod_picking

#

try with a few related crates to find if you have any duplicate deps

#

or just cargo tree -d I think, but there might be a lot of noise.

#

If it works for a button which picking events aren't working?

vernal token
#

Im on bevy 0.14.2

novel hamlet
#

right, but for what kind of entities

#

the events all use the same resource to fire, so if one works, they all work

novel hamlet
#

or egui if you have that

vernal token
novel hamlet
#

you're looking for the same package with different versions

vernal token
#

they're all bevy_mod_picking v0.20.1, so i guess we're good there.

#

egui is also fine

vernal token
# novel hamlet right, but for what kind of entities

This might be a complicated answer actually. And im not even sure if im answering ur question...but I made bunch of structs that look like this:

#[derive(Event, Debug)]
pub struct OnButton<E: Debug + Clone + Reflect>(pub ListenerInput<Pointer<E>>);
impl<E: Debug + Clone + Reflect> From<ListenerInput<Pointer<E>>> for OnButton<E> {
    fn from(event: ListenerInput<Pointer<E>>) -> Self {
        Self(event)
    }
}

I forgot why i did this tbh, but i did it early on when i first discovered the crate in order to reduce some boilerplate. I have one for each type of "thing" that needs to be pickable, and its worked fine ever since so i haven't reconsidered this. I register the event like so .add_event::<OnButton<Out>>() and then add On::<Pointer<Out>>::send_event::<OnButton<Out>>() on the button in question. The thing that isnt working is the OnCard one for my cards (its a card game). So really its just the name of the struct thats different, everything else is the same.

novel hamlet
#

I meant "what kind of entities are you picking". It sounds like bevy_ui only?

#

At this point, all I can think of is a breaking change in mod_picking 0.20.1, if you were on 0.20.0?

#

But that was released 4 months ago, so I'm not really sure what to make of this other than a local issue. The compiler issues you mention are a bit suspicious.

vernal token
novel hamlet
#

I don't think those have been touched recently

vernal token
#

i actually tried 0.20.0 but that didnt change anything

#

There are still some debugging steps i wanna try later, but thanks for trying πŸ™‚

novel hamlet
#

At this point I would look at the HoverMap to see what entities are being hit tested successfully. The events and listeners you are working with are all derived from that resource, for the most part. Things like drags and clicks are just looking at hits in the hover map, and pointer inputs, to determine when to send events.

vernal token
# novel hamlet At this point I would look at the `HoverMap` to see what entities are being hit ...

Made some progress from looking at the map. I noticed that it wasnt hitting the thing i was expecting, so i put a bunch of Pickable::IGNORE on them. But now im getting no hit data, so its like the cards (MaterialMesh2dBundles) are not even there.

MaterialMesh2dBundle {
    mesh: Mesh2dHandle(meshes.add(Rectangle::new(CARD_WIDTH, CARD_HEIGHT))),
    material: color_materials.add(Color::NONE),
    transform,
    ..default()
}
#

the pattern im seeing is that the SpriteBundles work, but not the Mesh2d

#

I just discovered PickableBundle...

#

So I tested the Mesh2d from the minimal 2d example and it does not show any hit data in the map

#

I could just drop Mesh2d all together, i guess, but this aint cool lol

vale zealot
#

How should I make the tooltip/popup show in full when the cursor is close to the edge? As shown in the screenshot, the rest of the text are truncated/off-screen.

vale zealot
#

Is it possible to display the Name of the Mesh(PbrBundle) in the tooltip?

commands.spawn((
    //         vvvvvvvv   show this name so that I can identify the meshes easily.
    Name::new("Original"),
    PbrBundle {
        mesh: shape,
        material: materials.add(Color::from(GREEN)),
        ..default()
    },
    Shape,
));
steady sage
vernal token
echo yew
#

I migrated from bevy_mod_picking to bevy_picking, but noticed that the debug UI (the one that follows the mouse) wasn't upstreamed. I find it extremely useful (especially the part that tells me which UI node is the one being pointed at), and plan on porting it over in my own app just so that I can get that feature back.

Before I do so, anyone else already has something similar to share?

marble pine
#

Or drop it in the bevy_editor_prototypes repo

placid sonnet
#

Hi I upgraded to 0.15 and I get an error on this:

*on_click = On::<Pointer<Click>>::run(|mut commands: Commands| {
                        commands.disconnect_client();
                    });

saying that the closure is not a valid system

#

I'm not entirely sure what's wrong, any ideas?

#

oh it hasn't been migrated to 0.15

#

Is it going to be upgraded or I should use bevy_picking?

#

Is there a guide to migrate to bevy_picking? the 0.14->0.15 migration docs don't have much

marble pine
#

@buoyant escarp didn't you write a big guide on the migration? Where did that end up?

buoyant escarp
#

yes; i have 90% of the 0.15 upgrade for picking done too, i've just not been able to allocate time to finishing it up

#

let me find that doc

placid sonnet
#

Actually i figured it out; i like the new observer-based approach

granite oyster
tepid sun
meager sky
#

This is probably not directly a problem with the picking.

BUT I have a system I want to run in the PreUpdate schedule, after picking has distributed the pointer events. and trying to add it with the line:

    // build the plugin
    fn build(&self, app: &mut App) {
        ...
        app.add_systems(PreUpdate, PointerTools::update_tools).after(events::pointer_events)

I get this error when trying to compile:

67 | pub struct App {
   | -------------- doesn't satisfy `App: SystemSet` or `App: bevy::prelude::IntoSystemSetConfigs`
   |
   = note: the following trait bounds were not satisfied:
           `&mut App: SystemSet`
           which is required by `&mut App: bevy::prelude::IntoSystemSetConfigs`
           `&&mut App: SystemSet`
           which is required by `&&mut App: bevy::prelude::IntoSystemSetConfigs`
           `&mut &mut App: SystemSet`
           which is required by `&mut &mut App: bevy::prelude::IntoSystemSetConfigs`
           `App: SystemSet`
           which is required by `App: bevy::prelude::IntoSystemSetConfigs`
           `&App: SystemSet`
           which is required by `&App: bevy::prelude::IntoSystemSetConfigs`

How should I go about specifying this ?
Thanks !

#

BTW Happy new Year πŸ™‚

novel hamlet
#

.after should be on the update_tools system

#

You are calling it on App

#

Just need to move it inside the )

meager sky
#

the ?

meager sky
meager sky
# novel hamlet .after should be on the update_tools system

Hmmm - I tried this and it compiled.
Understaning it though ( brain compiling ... ) πŸ™‚

             PointerManager::update_tools.after(bevy::picking::events::pointer_events))

update_tools is a function - do functions have default impl "methods" ? what is it looking for for "after".

#

Ok - starting to see - an added Trait generic which gets "passed" the type of the "pub fn(some queries)" for a system as the type (implicit) self of has the before, after, etc things that "configure" a "system entry" somewhere adding associated stuff associated with it.

novel hamlet
#

app.add_systems(PreUpdate, PointerTools::update_tools).after(events::pointer_events)
is calling after() on the output of add_systems(), which is App.
However, after() is a method you use to order systems. It is probably more clear when formatted like this:

app
    .add_systems(PreUpdate, PointerTools::update_tools)
    .after(events::pointer_events)

vs.

app.add_systems(
    PreUpdate, 
    PointerTools::update_tools.after(events::pointer_events)
)
meager sky
# novel hamlet `app.add_systems(PreUpdate, PointerTools::update_tools).after(events::pointer_ev...

So I see it as ".after(some system)" as a "method" on "update_tools" which is defined in a Trait as a "generic"

pub trait IntoSystemConfigs<Marker>
where
    Self: Sized,
{
...
    fn after<M>(self, set: impl IntoSystemSet<M>) -> SystemConfigs {
        self.into_configs().after(set)
    }
...
}

The syntax makes it look like .after(xx) is syntactically an impl "method" on the "system" function update_tools. What it looks like is the "self" in .after then has the type (and address of) of the update_tools (system/function) and registering the type as a system and setting it's config values ( mapped somewhere to the type in into_configs I guess ) .

Since one can't "add an interface/Trait" to a struct in other static typed languages that isn't intuitive to me (yet πŸ™‚ )
So the added Trait plus the expansion of the .after generic to resolve to the function to load the config at compile time is a new thing πŸ™‚

Anyway when coded as the below it does the proper thing πŸ™‚

app.add_systems(
    PreUpdate, 
    PointerTools::update_tools.after(events::pointer_events)
)

PK

tepid sun
#

By the looks of it this crate (or its functions) is getting integrated into bevy. I'm thinking of migrating due to 2dBundles being broken in 0.20.0.

However, I am dependent on the bevy_picking_highlight crate as well. Could I use it separately without bevy_mod_picking, given that I bump dependencies to 0.15.0?

buoyant escarp
#

this has already been integrated in the 0.15 release as bevy_picking

#

it should be possible to port the bevy_picking_highlight crate to the new system (on an infinite timeline i will do it, but i've been busy with other work recently).

#

the biggest issue with that crate is actually the changes to Handle<T> no longer being a component.

tepid sun
#

Sweet! I might give it a crack. Thank you

novel hamlet
#

Yeah, I will probably get around to updating all of those, but it is super duper low priority with the upstream available to users.