Getting the cursor world position in a Bevy 3D game with Rapier
There's a few ways already out there to capture the cursor in Bevy . If you're making a game in 2D space with an orthographic camera, there's some code in the Bevy Cheat Book. If you're creating a game in 3D space, and need to select entities, there is bevy_mod_picking.
I needed the world coordinates of my mouse, not a picker. I'm also using Rapier. The prospect using Rapier's physics system - instead of including another library - looked compelling.
This method might not work depending on how your game is set up. I've only tested in a 3D perspective camera world. Additionally, the cursor position will only update when moved on the client-side. This can be an issue if the camera moves. The world position of the cursor may change without the device moving, but no update event will send.
Ray extension traits
To get the mouse position, we need to cast a ray from our camera.
Now we have some methods (mainly
from_window) that we can call to get a rapier
Ray. We can use this to check for collisions.
Getting the cursor
In my case, I needed to get the cursor's position projected on a 2D plane (parallel to the camera's view). To do this in Rapier, we can use a
I also wanted to save these coordinates in a resource to access in my other systems.
We don't have to test on a
HalfSpace, we can use any shape with any transform. (If you are applying a transform, use
.cast_ray instead of
.cast_local_ray.) We can also use this rapier
Ray to test for collisions on entities, and create a simple picker.