From 48746ce3a46edd68d77e53261e04cc2885bcd3a2 Mon Sep 17 00:00:00 2001 From: Malcolm Nixon Date: Mon, 3 Jun 2024 23:18:53 -0400 Subject: [PATCH] Fix slope-sliding by applying ground-friction at the correct time in the calculations. Fix ground-control preventing jumping over objects. --- VERSIONS.md | 2 + addons/godot-xr-tools/player/player_body.gd | 64 +++++++++++---------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/VERSIONS.md b/VERSIONS.md index cb551cc3..b2f8787e 100644 --- a/VERSIONS.md +++ b/VERSIONS.md @@ -1,6 +1,8 @@ # 4.3.2 - Move fade logic into effect - Added collision fade support +- Added fix for slowly sliding on slopes +- Added fix for ground-control preventing jumping over objects # 4.3.1 - Fix saving project when using plugin-tools to set physics layers or enable OpenXR diff --git a/addons/godot-xr-tools/player/player_body.gd b/addons/godot-xr-tools/player/player_body.gd index 6dc9fd96..8ab3af5a 100644 --- a/addons/godot-xr-tools/player/player_body.gd +++ b/addons/godot-xr-tools/player/player_body.gd @@ -669,39 +669,33 @@ func _apply_velocity_and_control(delta: float): var vertical_velocity := local_velocity - horizontal_velocity # If the player is on the ground then give them control - if _can_apply_ground_control(): + if _can_apply_ground_control() and ground_control_velocity.length() >= 0.1: # If ground control is being supplied then update the horizontal velocity var control_velocity := Vector3.ZERO - if abs(ground_control_velocity.x) > 0.1 or abs(ground_control_velocity.y) > 0.1: - var camera_transform := camera_node.global_transform - var dir_forward := camera_transform.basis.z.slide(up_gravity).normalized() - var dir_right := camera_transform.basis.x.slide(up_gravity).normalized() - control_velocity = ( - dir_forward * -ground_control_velocity.y + - dir_right * ground_control_velocity.x - ) * XRServer.world_scale - - # Apply control velocity to horizontal velocity based on traction - var current_traction := XRToolsGroundPhysicsSettings.get_move_traction( - ground_physics, default_physics) - var traction_factor: float = clamp(current_traction * delta, 0.0, 1.0) - horizontal_velocity = horizontal_velocity.lerp(control_velocity, traction_factor) - - # Prevent the player from moving up steep slopes - var current_max_slope := XRToolsGroundPhysicsSettings.get_move_max_slope( - ground_physics, default_physics) - if ground_angle > current_max_slope: - # Get a vector in the down-hill direction - var down_direction := ground_vector.slide(up_gravity).normalized() - var vdot: float = down_direction.dot(horizontal_velocity) - if vdot < 0: - horizontal_velocity -= down_direction * vdot - else: - # User is not trying to move, so apply the ground drag - var current_drag := XRToolsGroundPhysicsSettings.get_move_drag( - ground_physics, default_physics) - var drag_factor: float = clamp(current_drag * delta, 0, 1) - horizontal_velocity = horizontal_velocity.lerp(control_velocity, drag_factor) + var camera_transform := camera_node.global_transform + var dir_forward := camera_transform.basis.z.slide(up_gravity).normalized() + var dir_right := camera_transform.basis.x.slide(up_gravity).normalized() + control_velocity = ( + dir_forward * -ground_control_velocity.y + + dir_right * ground_control_velocity.x + ) * XRServer.world_scale + + # Apply control velocity to horizontal velocity based on traction + var current_traction := XRToolsGroundPhysicsSettings.get_move_traction( + ground_physics, default_physics) + var traction_factor: float = clamp(current_traction * delta, 0.0, 1.0) + horizontal_velocity = horizontal_velocity.lerp(control_velocity, traction_factor) + + # Prevent the player from moving up steep slopes + if on_ground: + var current_max_slope := XRToolsGroundPhysicsSettings.get_move_max_slope( + ground_physics, default_physics) + if ground_angle > current_max_slope: + # Get a vector in the down-hill direction + var down_direction := ground_vector.slide(up_gravity).normalized() + var vdot: float = down_direction.dot(horizontal_velocity) + if vdot < 0: + horizontal_velocity -= down_direction * vdot # Combine the velocities back to a 3-space velocity local_velocity = horizontal_velocity + vertical_velocity @@ -709,6 +703,14 @@ func _apply_velocity_and_control(delta: float): # Move the player body with the desired velocity velocity = move_body(local_velocity + ground_velocity) + # Apply ground-friction after the move + if _can_apply_ground_control() and ground_control_velocity.length() < 0.1: + # User is not trying to move, so apply the ground drag + var current_drag := XRToolsGroundPhysicsSettings.get_move_drag( + ground_physics, default_physics) + var drag_factor: float = clamp(current_drag * delta, 0, 1) + velocity = velocity.lerp(ground_velocity, drag_factor) + # Perform bounce test if a collision occurred if get_slide_collision_count(): # Get the collider the player collided with