-
Notifications
You must be signed in to change notification settings - Fork 44
Character controller #96
Comments
Yes, I aggree. But sadly that's rapier behavior. And I'm not eager to solve this problem in After all, even if To be honest, I had the same feeling when I started to use rapier (as I'm coming from Godot). But I realized, that instead of using a kinematic body for a player character, I could use a dynamic body, and only make sure to redefine the body velocity before each physics step. Maybe it is just that a "kinematic body" is the best choice for a player character in godot (because of that higher level API), but with rapier it is "dynamic body" which is the best choice for a player character. If you really want this feature, you can propose a PR. But, if that's the case, your efforts may be better spent on adding this feature to Maybe later, after addressing more pressing issues (offset, multiple-shapes-per-body, ray-cast, layers, etc.), I may have a closer look at this. But when that day will come, I'll probably consider contribute the feature to rapier directly. |
Makes total sense, in fact I was checking Rapier's roadmap for this year just now and it says:
As you suggests, maybe it's better to just wait for that feature to land, and then rework it in Heron if necessary, or to contribute it directly to Rapier. |
For what it's worth, this is the approach I've been taking and it is working well so far: simplescreenrecorder-2021-06-22_09.43.50.mp4I just set the velocity of the player every frame, and if I try to push him into a wall he just stops, as you would expect. In the video it only looks like he's moving jaggedly because I'm changing my direction diagonal as I push into the blue triangle. Here's the code if anybody wants to check it out. ( keep in mind I have some of my own extension to the physics for generating sprite collision shapes in that example ) |
I think this should be fixed in Issue #140 |
With kinematicallysad.mp4// Paltform
fn spawn_world(
mut commands: Commands,
) {
// The ground
let size = Vec2::new(1000.0, 50.0);
commands
// Spawn a bundle that contains at least a `GlobalTransform`
.spawn_bundle(SpriteBundle {
sprite: Sprite {
color: Color::WHITE,
custom_size: Some(size),
..Default::default()
},
transform: Transform::from_translation(Vec3::new(0.0, -300.0, 0.0)),
..Default::default()
})
// Make it a rigid body
.insert(RigidBody::Static)
// Attach a collision shape
.insert(CollisionShape::Cuboid {
half_extends: size.extend(0.0) / 2.0,
border_radius: None,
});
} // Player
#[derive(Default, Component)]
struct Movement {
gravity: f32,
}
#[derive(Bundle)]
struct PhysicsBundle {
movement: Movement,
rigidbody: RigidBody,
collision: CollisionShape,
motion_velocity: Velocity,
}
pub fn setup(
mut commands: Commands,
) {
// ....... some unrelated code
.insert_bundle(PhysicsBundle {
movement: Movement {
gravity: 37.5,
..Default::default()
},
rigidbody: RigidBody::KinematicVelocityBased,
collision: CollisionShape::Cuboid {
half_extends: Vec2::new(32.0 * 6.0, 32.0 * 6.0).extend(0.0) / 2.0,
border_radius: None,
},
motion_velocity: Velocity::default(),
});
}
fn movement_system(
mut query: Query<(&mut Movement, &mut Velocity)>,
) {
let (mut movement, mut motion_velocity) = query.single_mut();
motion_velocity.linear.y -= movement.gravity;
} Is there a similar function to Godot's Edit: Another question, how to get delta time as now it seems that the faster the computer a user has, the faster the physics are? |
That's expected behavior. If it is kinematic, it means you are controlling the movement, and the phyiscs engine will not alter that, not even to prevent inter-penetration.
No. Mostly because rapier doesn't have that functionallity. And I would prefer to see that solved in rapier first (see my first answer in this issue)
If you use the default settings you may use the time resource normally. For more complex setups, you may retrieve the configured time from the |
It's particularly unclear how to handle this in situations with gravity. Simply zeroing out velocity every tick isn't sufficient, as you lose gravity, and it's possible (though lower priority) that you do want some non-static bodies to impart forces on your character. There's a recently opened issue on Rapier for this: dimforge/rapier#307 |
Right now, the only way to control kinematic bodies is by manually changing their transform. However, collisions are not taken into account by default, delegating that logic to the final user. This would be really useful to have even in basic games, such as platformers, where the player needs to collide with the floor.
For instance, Godot includes some high-level functions to handle this behavior, as explained in its documentation: Movement and collision and Detecting collisions.
This was discussed a while ago in the Bevy's discord physics channel, where Rapier's developer said:
The text was updated successfully, but these errors were encountered: