From 69bf70060c6344bc1d68de2cc0da5d4e1e34dc5e Mon Sep 17 00:00:00 2001 From: Jonas H Date: Mon, 6 Apr 2026 20:40:17 +0200 Subject: [PATCH] fixed player rotation --- src/components/movement.rs | 2 + src/states/player_states.rs | 85 +++++++++++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 14 deletions(-) diff --git a/src/components/movement.rs b/src/components/movement.rs index 9d0fd22..ade249d 100644 --- a/src/components/movement.rs +++ b/src/components/movement.rs @@ -41,6 +41,7 @@ pub struct MovementContext pub is_floored: bool, pub last_floored_time: u64, pub surface_normal: Vec3, + pub last_walk_direction: Vec3, } impl MovementContext @@ -52,6 +53,7 @@ impl MovementContext is_floored: false, last_floored_time: 0, surface_normal: Vec3::Y, + last_walk_direction: Vec3::Z, } } } diff --git a/src/states/player_states.rs b/src/states/player_states.rs index 17205a7..ec6db66 100644 --- a/src/states/player_states.rs +++ b/src/states/player_states.rs @@ -1,4 +1,4 @@ -use glam::Vec3; +use glam::{Quat, Vec3}; use kurbo::ParamCurve; use rapier3d::math::Vector; @@ -84,6 +84,25 @@ impl State for IdleState }); } } + + let last_dir = world + .movements + .with(entity, |m| m.movement_context.last_walk_direction) + .unwrap_or(Vec3::Z); + let yaw = f32::atan2(last_dir.x, last_dir.z); + world.transforms.with_mut(entity, |transform| { + transform.rotation = Quat::from_rotation_y(yaw); + }); + world.physics.with(entity, |physics| { + PhysicsManager::with_rigidbody_mut(physics.rigidbody, |rb| { + rb.set_next_kinematic_rotation( + rapier3d::na::UnitQuaternion::from_axis_angle( + &rapier3d::na::Vector3::y_axis(), + yaw, + ), + ); + }); + }); } } @@ -196,9 +215,23 @@ impl State for WalkingState if movement_input.length_squared() > 0.1 { + let walk_dir = movement_input.normalize(); + world.movements.with_mut(entity, |movement| { + movement.movement_context.last_walk_direction = walk_dir; + }); + let target_rotation = f32::atan2(movement_input.x, movement_input.z); world.transforms.with_mut(entity, |transform| { - let target_rotation = f32::atan2(movement_input.x, movement_input.z); - transform.rotation.y = target_rotation; + transform.rotation = Quat::from_rotation_y(target_rotation); + }); + world.physics.with(entity, |physics| { + PhysicsManager::with_rigidbody_mut(physics.rigidbody, |rb| { + rb.set_next_kinematic_rotation( + rapier3d::na::UnitQuaternion::from_axis_angle( + &rapier3d::na::Vector3::y_axis(), + target_rotation, + ), + ); + }); }); } } @@ -353,6 +386,25 @@ impl State for FallingState world.movements.with_mut(entity, |movement| { movement.movement_context.is_floored = is_grounded; }); + + let last_dir = world + .movements + .with(entity, |m| m.movement_context.last_walk_direction) + .unwrap_or(Vec3::Z); + let yaw = f32::atan2(last_dir.x, last_dir.z); + world.transforms.with_mut(entity, |transform| { + transform.rotation = Quat::from_rotation_y(yaw); + }); + world.physics.with(entity, |physics| { + PhysicsManager::with_rigidbody_mut(physics.rigidbody, |rb| { + rb.set_next_kinematic_rotation( + rapier3d::na::UnitQuaternion::from_axis_angle( + &rapier3d::na::Vector3::y_axis(), + yaw, + ), + ); + }); + }); } } @@ -368,11 +420,8 @@ impl State for LeapingState self.time_in_state = 0.0; let facing = world - .transforms - .with(entity, |t| { - let yaw = t.rotation.y; - Vec3::new(yaw.sin(), 0.0, yaw.cos()) - }) + .movements + .with(entity, |m| m.movement_context.last_walk_direction) .unwrap_or(Vec3::Z); let move_dir = world @@ -424,8 +473,19 @@ impl State for LeapingState m.movement_context.is_floored = terrain_height.is_some(); }); + let yaw = f32::atan2(self.leap_direction.x, self.leap_direction.z); world.transforms.with_mut(entity, |t| { - t.rotation.y = f32::atan2(self.leap_direction.x, self.leap_direction.z); + t.rotation = Quat::from_rotation_y(yaw); + }); + world.physics.with(entity, |physics| { + PhysicsManager::with_rigidbody_mut(physics.rigidbody, |rb| { + rb.set_next_kinematic_rotation( + rapier3d::na::UnitQuaternion::from_axis_angle( + &rapier3d::na::Vector3::y_axis(), + yaw, + ), + ); + }); }); } } @@ -447,11 +507,8 @@ impl State for RollingState .filter(|d| d.length_squared() > 0.01) .unwrap_or_else(|| { world - .transforms - .with(entity, |t| { - let yaw = t.rotation.y; - Vec3::new(yaw.sin(), 0.0, yaw.cos()) - }) + .movements + .with(entity, |m| m.movement_context.last_walk_direction) .unwrap_or(Vec3::Z) }); }