bevy_xpbd
bevy_xpbd copied to clipboard
Colliders bouncing on trimesh collider
I am creating a voxel game in bevy using avian3d for the physics. Attached is a video showing the unexpected behavior when a rectangular cuboid is accelerated over a trimesh. Causing this strange bouncing effect. How can I stop this bouncing from happening as I am attempting to achieve minecraft like smooth movement. I can more complete code examples if necessary
https://github.com/user-attachments/assets/02ceafa6-81e7-4079-923c-06eb7e48b53f
Code Snippets:
fn move_player( keys: Res<ButtonInput<KeyCode>>, mut player: Query<(&mut LinearVelocity, Entity), With<Player>>, camera: Query<&Transform, With<WorldModelCamera>>, spatial_query: SpatialQuery, ) { // Called on update // How the player is moved let Ok((mut velocity, player_entity)) = player.get_single_mut() else { return; }; let Ok(transform) = camera.get_single() else { return; };
let forward = transform.forward();
let horizontal = Vec2::new(forward.x, forward.z).normalize_or(Vec2::new(1.0, 0.0));
if keys.pressed(KeyCode::KeyW) {
velocity.x = MOVE_SPEED * horizontal.x;
velocity.z = MOVE_SPEED * horizontal.y;
}
}
// Following is outlines how chunk is spawned. // generate_chunk mesh returns a mesh and bool vec, all works as seen with visible mesh
let chunk_mesh = generate_chunk_mesh(chunk_data);
let chunk = commands.spawn(( Mesh3d(meshes.add(chunk_mesh.0.clone())), MeshMaterial3d(material_handle.clone()), Transform::from_xyz( (i as f32 - 32.0) * 15.0 - (RENDER_DISTANCE_HALF as f32 * 15.0), (j as f32 - 32.0) * 15.0 - (RENDER_DISTANCE_HALF as f32 * 15.0), (k as f32 - 32.0) * 15.0 - (RENDER_DISTANCE_HALF as f32 * 15.0), ), GlobalTransform::default(), Visibility::default(), RigidBody::Static, Collider::trimesh_from_mesh(&chunk_mesh.0.clone()).unwrap(), )).id(); commands.entity(chunk_entity).add_children(&[chunk]);
// Player spawn (from bevy first person example, slightly modified) pub fn spawn_view_model( mut commands: Commands, mut meshes: ResMut<Assets<Mesh>>, mut materials: ResMut<Assets<StandardMaterial>>, ) { let arm = meshes.add(Cuboid::new(0.1, 0.1, 0.5)); let arm_material = materials.add(Color::from(tailwind::TEAL_200));
commands
.spawn((
Player,
Transform::from_xyz(0.0, 1.0, 0.0),
Visibility::default(),
RigidBody::Dynamic,
//Collider::capsule(0.3, 2.0),
Collider::cuboid(0.9,1.8,0.9),
LockedAxes::ROTATION_LOCKED,
//Friction::new(0.0),
Restitution::ZERO.with_combine_rule(CoefficientCombine::Min),
))
.with_children(|parent| {
parent.spawn((
WorldModelCamera,
CameraSensitivity::default(),
Camera3d::default(),
Projection::from(PerspectiveProjection {
fov: 60.0_f32.to_radians(), // originally 90 deg
..default()
}),
));
// Spawn view model camera.
parent.spawn((
Camera3d::default(),
Camera {
// Bump the order to render on top of the world model.
order: 1,
..default()
},
Projection::from(PerspectiveProjection {
fov: 70.0_f32.to_radians(),
..default()
}),
// Only render objects belonging to the view model.
RenderLayers::layer(VIEW_MODEL_RENDER_LAYER),
));
// Spawn the player's right arm. MeshMaterial3d(materials.add(Color::srgb_u8(124, 144, 255))),
parent.spawn((
Mesh3d(arm),
MeshMaterial3d(arm_material),
Transform::from_xyz(0.2, -0.1, -0.25),
// Ensure the arm is only rendered by the view model camera.
RenderLayers::layer(VIEW_MODEL_RENDER_LAYER),
// The arm is free-floating, so shadows would look weird.
NotShadowCaster,
));
});