diff --git a/game/src/systems/kinematic_character_controller.rs b/game/src/systems/kinematic_character_controller.rs index 41561a5..fd031c5 100644 --- a/game/src/systems/kinematic_character_controller.rs +++ b/game/src/systems/kinematic_character_controller.rs @@ -1,7 +1,7 @@ use glam::{Quat, Vec3}; -use rapier3d::prelude::{nalgebra, ColliderBuilder, QueryFilter, RigidBodyBuilder}; +use rapier3d::prelude::{nalgebra, ColliderBuilder, QueryFilter, RigidBodyBuilder, RigidBodyType}; use rapier3d::prelude::vector; -use rapier3d::control::KinematicCharacterController as RapierKinematicCharacterController; +use rapier3d::control::{CharacterCollision, KinematicCharacterController as RapierKinematicCharacterController}; use rapier3d::na::{Isometry3, Vector3}; use winit::event::DeviceEvent::MouseMotion; use winit::event::Event; @@ -53,7 +53,7 @@ impl System for KinematicCharacterController { )); self.speed = 5.0; - self.sensitivity = 0.1; + self.sensitivity = 0.05; self.gravity = -9.81; self.max_fall_speed = -50.0; self.vertical_velocity = 0.0; @@ -141,13 +141,14 @@ impl System for KinematicCharacterController { let mut total_displacement = self.desired_movement; total_displacement.y += self.vertical_velocity * pctx.time_ctx.fixed_dt; + let mut collisions: Vec = Vec::new(); let corrected_movement = self.character_controller.move_shape( pctx.time_ctx.fixed_dt, &query_pipeline, &*self.character_collider.shape, &Isometry3::from(self.last_position), vector![total_displacement.x, total_displacement.y, total_displacement.z], - |_| {}, + |collision| collisions.push(collision), ); // update character rigid body with the new translation. @@ -165,6 +166,22 @@ impl System for KinematicCharacterController { } } + // apply impulses to dynamic bodies the character collided with + let character_push_force = 50.0; + for collision in collisions { + if let Some(collider) = p.collider_set.get(collision.handle) { + if let Some(rb_handle) = collider.parent() { + if let Some(rb) = p.rigid_body_set.get_mut(rb_handle) { + if rb.body_type() == RigidBodyType::Dynamic { + let push_direction = -collision.hit.normal1.into_inner(); + let impulse = push_direction * character_push_force * pctx.time_ctx.fixed_dt; + rb.apply_impulse(impulse, true); + } + } + } + } + } + self.desired_movement = Vec3::ZERO; } }