Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inaccurate collisions when using a lot of ColliderShapes with the same height #124

Open
daxpedda opened this issue Feb 27, 2022 · 2 comments
Labels
A-Dynamics C-Bug Something isn't working D-Difficult Needs strong technical background, domain knowledge, or impacts are high, needs testing... P-Medium S-not-started Work has not started

Comments

@daxpedda
Copy link

daxpedda commented Feb 27, 2022

When programming a simple platformer, building a straight path out of many ColliderShapes and having a character walk on it doesn't work.

I am assuming that the issue is that the y-coordinate of every ColliderShape is not exactly the same, because of f32 inaccuracies. So the character walks along the straight path but bumps into a block that isn't exactly on the same y-coordinate as the one before it.

Example code
use bevy::prelude::*;
use bevy_rapier2d::prelude::*;

const SCALE: f32 = 16.;
const PLATFORM_Y: f32 = -8.;
const TILES: isize = 100;
const CONTROLLER_JUMP_IMPULSE: f32 = 15.;

fn main() {
  let mut app = App::new();
  app.add_plugins(DefaultPlugins);
  app.add_plugin(RapierRenderPlugin);
  app.add_plugin(RapierPhysicsPlugin::<NoUserData>::default());
  app.add_startup_system(setup)
  	.add_system(movement);

  app.run()
}

#[derive(Component)]
struct Controller;

fn setup(mut commands: Commands, mut rapier_config: ResMut<RapierConfiguration>) {
  commands
  	.spawn()
  	.insert_bundle(OrthographicCameraBundle::new_2d());

  rapier_config.scale = SCALE;

  commands
  	.spawn()
  	.insert_bundle(RigidBodyBundle {
  		mass_properties: RigidBodyMassPropsFlags::ROTATION_LOCKED.into(),
  		..Default::default()
  	})
  	.insert_bundle(SpriteBundle {
  		sprite: Sprite {
  			color: Color::rgb(1., 0., 0.),
  			custom_size: Some(Vec2::new(1. * SCALE, 2. * SCALE)),
  			..Default::default()
  		},
  		..Default::default()
  	})
  	.insert_bundle(ColliderBundle {
  		shape: ColliderShape::cuboid(0.5, 1.).into(),
  		..Default::default()
  	})
  	.insert(ColliderPositionSync::Discrete).insert(Controller);

  for x in -TILES / 2..TILES / 2 {
  	commands
  		.spawn()
  		.insert_bundle(SpriteBundle {
  			sprite: Sprite {
                  color: Color::rgb(0., 1., 0.),
                  custom_size: Some(Vec2::new(1. * SCALE, 1. * SCALE)),
                  ..Default::default()
              },
  			transform: Transform::from_xyz(x as f32 * SCALE, PLATFORM_Y * SCALE, 0.),
  			..Default::default()
  		})
  		.insert_bundle(ColliderBundle {
  			shape: ColliderShape::cuboid(0.5, 0.5).into(),
  			position: [x as f32, PLATFORM_Y].into(),
  			..Default::default()
  		});
  }
}

fn movement(
  keyboard_input: Res<Input<KeyCode>>,
  mut controller: Query<(
  	&mut RigidBodyForcesComponent,
  	&mut RigidBodyVelocityComponent,
  	&RigidBodyMassPropsComponent,
  	&mut ColliderMaterialComponent,
  ), With<Controller>>,
) {
  let (mut rb_forces, mut rb_vel, rb_mprops, mut co_material) = controller.single_mut();

  if keyboard_input.just_pressed(KeyCode::Space) {
  	rb_vel.apply_impulse(rb_mprops, Vec2::new(0., CONTROLLER_JUMP_IMPULSE).into());
  }

  let mut x_axis = 0.;

  if keyboard_input.pressed(KeyCode::A) || keyboard_input.pressed(KeyCode::Left) {
  	x_axis -= 1.;
  } else if keyboard_input.pressed(KeyCode::D) || keyboard_input.pressed(KeyCode::Right) {
  	x_axis += 1.;
  }

  if x_axis == 0. {
  	co_material.friction = 2.;
  } else {
      co_material.friction = 0.;
  	x_axis *= 25. * rb_mprops.mass();
  	rb_forces.force.x = x_axis;
  }
}

Somebody else had this issue before, probably with a better explanation of what the issue is about: https://dev.to/sbelzile/making-games-in-rust-part-7-fixing-the-player-randomly-stuck-issue-3mj5.

@daxpedda daxpedda changed the title Inaccurate collisions on Inaccurate collisions when using a lot of ColliderShapes with the same height Feb 27, 2022
@brandon-reinhart
Copy link

brandon-reinhart commented Sep 1, 2022

I've run into this as well, but meshing all of the tiles is probably the right solution anyway. Still annoying that it blocks quick n' dirty tests.

@Vrixyz Vrixyz added C-Bug Something isn't working P-Medium S-not-started Work has not started A-Dynamics labels May 24, 2024
@Vrixyz
Copy link
Contributor

Vrixyz commented May 24, 2024

I think that's a rapier issue, but I agree it would be convenient to be able to have a smoother experience for "quick n' dirty tests".

Any update on reproduction code is appreciated.

@Vrixyz Vrixyz added the D-Difficult Needs strong technical background, domain knowledge, or impacts are high, needs testing... label May 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Dynamics C-Bug Something isn't working D-Difficult Needs strong technical background, domain knowledge, or impacts are high, needs testing... P-Medium S-not-started Work has not started
Projects
None yet
Development

No branches or pull requests

3 participants