wip: fixing physics

feat/player-physics
hheik 2022-12-16 16:42:08 +02:00
parent 352fca7093
commit 50367637b1
3 changed files with 36 additions and 15 deletions

View File

@ -15,7 +15,7 @@ noise = "0.8.2"
# Enable a small amount of optimization in debug mode # Enable a small amount of optimization in debug mode
[profile.dev] [profile.dev]
opt-level = 1 opt-level = 0
# Enable high optimizations for dependencies (incl. Bevy), but not for our code: # Enable high optimizations for dependencies (incl. Bevy), but not for our code:
[profile.dev.package."*"] [profile.dev.package."*"]

View File

@ -42,7 +42,7 @@ impl Default for KinematicBundle {
#[derive(Component, Reflect, Default)] #[derive(Component, Reflect, Default)]
#[reflect(Component)] #[reflect(Component)]
pub struct KinematicState { pub struct KinematicState {
// TODO: fork rapier2d and make it reflect? // TODO: fork rapier2d to make it reflect?
#[reflect(ignore)] #[reflect(ignore)]
pub last_move: Option<MoveShapeOutput>, pub last_move: Option<MoveShapeOutput>,
pub did_jump: bool, pub did_jump: bool,
@ -103,6 +103,7 @@ fn kinematic_movement(
child_query: Query<&Children>, child_query: Query<&Children>,
mut rapier_context: ResMut<RapierContext>, mut rapier_context: ResMut<RapierContext>,
) { ) {
let dt = rapier_context.integration_parameters.dt;
for (entity, mut kinematic_state, mut transform, props, global_transform, input) in for (entity, mut kinematic_state, mut transform, props, global_transform, input) in
query.iter_mut() query.iter_mut()
{ {
@ -128,9 +129,9 @@ fn kinematic_movement(
let current_velocity = kinematic_state let current_velocity = kinematic_state
.last_move .last_move
.as_ref() .as_ref()
.map_or(Vec2::ZERO, |last| last.effective_translation); .map_or(Vec2::ZERO, |last| last.effective_translation) / dt;
let target_velocity = let target_velocity =
input.movement * speed + current_velocity.project_onto_normalized(GRAVITY_DIR); input.movement * speed;
let angle_lerp = if current_velocity.length_squared() > 0.01 { let angle_lerp = if current_velocity.length_squared() > 0.01 {
let result = inverse_lerp( let result = inverse_lerp(
@ -151,11 +152,23 @@ fn kinematic_movement(
let delta_interpolation = angle_lerp.clamp(0.0, 1.0); let delta_interpolation = angle_lerp.clamp(0.0, 1.0);
let velocity_change_speed = lerp(acceleration, friction, delta_interpolation) * speed; let velocity_change_speed = lerp(acceleration, friction, delta_interpolation) * speed;
let mut velocity = move_towards_vec2( let mut velocity = if let Some(gravity) = props.gravity {
current_velocity, move_towards_vec2(
target_velocity, current_velocity,
velocity_change_speed * time.delta_seconds(), target_velocity.reject_from_normalized(GRAVITY_DIR) + current_velocity.project_onto_normalized(GRAVITY_DIR),
); velocity_change_speed * dt,
) + GRAVITY_DIR * gravity * dt
} else {
move_towards_vec2(
current_velocity,
target_velocity,
velocity_change_speed * dt,
)
};
if velocity.y > 0.01 || velocity.y < -0.01 {
println!("vertical velocity: {velocity:?}")
}
if input.want_jump && kinematic_state.can_jump() { if input.want_jump && kinematic_state.can_jump() {
velocity = Vec2 { velocity = Vec2 {
@ -177,7 +190,7 @@ fn kinematic_movement(
// gravity // gravity
if let Some(gravity) = props.gravity { if let Some(gravity) = props.gravity {
velocity.y += -9.81 * gravity * time.delta_seconds(); velocity.y += -9.81 * gravity * dt;
} }
// move // move
@ -199,17 +212,20 @@ fn kinematic_movement(
..MoveShapeOptions::default() ..MoveShapeOptions::default()
}; };
let last_move = rapier_context.move_shape( let last_move: MoveShapeOutput = rapier_context.move_shape(
velocity * time.delta_seconds(), velocity * dt,
// Vec2::X * dt,
shape, shape,
translation.truncate(), translation.truncate(),
rotation.to_euler(EulerRot::ZYX).0, rotation.to_euler(EulerRot::ZYX).0,
shape.raw.0.mass_properties(1.0).mass(), shape.raw.0.mass_properties(1.0).mass(),
move_options, move_options,
QueryFilter::new(), QueryFilter::new(),
|coll: CharacterCollision| println!("Collided! {coll:?}"), |_coll: CharacterCollision| (),
); );
// println!("moved: {moved:?}, diff: {diff:?}", moved=last_move.effective_translation, diff=(velocity * dt - last_move.effective_translation));
// Apply movement // Apply movement
transform.translation += last_move.effective_translation.extend(0.0); transform.translation += last_move.effective_translation.extend(0.0);

View File

@ -38,8 +38,9 @@ pub fn player_system(
let movement = Vec2 { let movement = Vec2 {
x: input_to_axis(input.pressed(KeyCode::A), input.pressed(KeyCode::D)), x: input_to_axis(input.pressed(KeyCode::A), input.pressed(KeyCode::D)),
// y: input_to_axis(input.pressed(KeyCode::S), input.pressed(KeyCode::W)), // x: -1.0,
y: 0.0, y: input_to_axis(input.pressed(KeyCode::S), input.pressed(KeyCode::W)),
// y: 0.0,
}; };
kinematic_input.movement = movement; kinematic_input.movement = movement;
@ -62,6 +63,10 @@ pub fn player_spawn(mut commands: Commands) {
transform: TransformBundle::from_transform(Transform::from_translation(Vec3::new( transform: TransformBundle::from_transform(Transform::from_translation(Vec3::new(
256.0, 128.0, 0.0, 256.0, 128.0, 0.0,
))), ))),
properties: KinematicProperties {
gravity: None,
..default()
},
..default() ..default()
}; };