diff --git a/godot/player/OnFootPhysics.gd b/godot/player/OnFootPhysics.gd index 2224ffd..31f558f 100644 --- a/godot/player/OnFootPhysics.gd +++ b/godot/player/OnFootPhysics.gd @@ -2,15 +2,26 @@ extends KinematicBody onready var util = get_node("/root/Util") -export var gravity: float = 2.5 +export var gravity: float = 6.0 +# When falling, gravity is artificially increased +export var gravity_downwards_factor: float = 2 +# Rate of gaining speed +export var velocity_acceleration_xz: float = 3 +export var velocity_acceleration_y: float = 5 +# Rate of losing speed when stopping +export var velocity_friction_xz: float = 15 +export var velocity_friction_y: float = 1 +export var jump_power: float = 50 + +# Controls the base speeds of walking and sprinting +export var sprint_factor: float = 1.5 +export var walk_factor: float = 1.0 + +export var max_xz_speed: float = 2 + "public" var velocity: Vector3 = Vector3.ZERO -export var velocity_acceleration: float = 5 -export var velocity_friction: float = 5 -export var jump_power: float = 125 -export var sprint_factor: float = 1.07 - +# Value changed by code only to add slow down or speed up effects var velocity_factor: Vector3 = Vector3.ONE - var target_velocity: Vector3 = Vector3.ZERO var is_jumping: bool = false var jump_permission: float = 1.0 @@ -30,7 +41,10 @@ func process_velocity(delta: float): # Gravity # You can buffer jumps by pressing releaseing the space bar and then pressing it again if not is_on_floor(): - target_velocity.y = -gravity + var grav = -gravity + target_velocity.y = grav + # Gravity is stronger when you're falling. Feels nicer + target_velocity.y *= util.clamped_lerp(gravity_downwards_factor, 1.0, velocity.y/2, 0.0) else: velocity.y = max(0.0, velocity.y) target_velocity.y = max(0.0, max(target_velocity.y, jump_power * $"../MovementInput".jump_intent * jump_permission)) @@ -44,35 +58,36 @@ func process_velocity(delta: float): var target_velocity_xz = $"../MovementInput".input_xz target_velocity = util.vec2_xz_to_vec3(target_velocity_xz, target_velocity.y) - var velocity_xz = util.vec3_xz(velocity) - var xz_weight = velocity_acceleration * delta - if target_velocity_xz.length() < velocity_xz.length(): - xz_weight = velocity_friction * delta - var target_xz_length = lerp(velocity_xz.length(), target_velocity_xz.length(), xz_weight) + + var xz_weight = velocity_acceleration_xz * delta + if target_velocity_xz.length() < velocity_xz.length(): + xz_weight = velocity_friction_xz * delta + + var target_xz_length = util.clamped_lerp(velocity_xz.length(), target_velocity_xz.length(), xz_weight, 0.25) + if target_velocity_xz != Vector2.ZERO: velocity_xz = target_velocity_xz.normalized() * target_xz_length elif velocity_xz != Vector2.ZERO: velocity_xz = velocity_xz.normalized() * target_xz_length - - if (target_velocity_xz - velocity_xz).length() <= 0.025: - velocity_xz = target_velocity_xz - var y_weight = velocity_acceleration * delta + var y_weight = velocity_acceleration_y * delta if target_velocity.y < velocity.y: - y_weight = velocity_friction * delta + y_weight = velocity_friction_y * delta - var velocity_y = lerp(velocity.y, target_velocity.y, y_weight) - if abs(target_velocity.y - velocity_y) <= 0.025: - velocity_y = target_velocity.y + var velocity_y = util.clamped_lerp(velocity.y, target_velocity.y, y_weight, 0.25) if $"../MovementInput".sprinting: velocity_xz *= sprint_factor + else: + velocity_xz *= walk_factor velocity = util.vec2_xz_to_vec3(velocity_xz, velocity_y) * velocity_factor + velocity = util.vec2_xz_to_vec3(util.vec3_xz(velocity).limit_length(max_xz_speed), velocity.y) + func increase_velocity_factor(by: Vector3): velocity_factor *= by diff --git a/godot/tests/test_player_locomotion.tscn b/godot/tests/test_player_locomotion.tscn index 9e566dc..afe8e3a 100644 --- a/godot/tests/test_player_locomotion.tscn +++ b/godot/tests/test_player_locomotion.tscn @@ -10,7 +10,7 @@ data = PoolVector3Array( -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1 [node name="test_player_locomotion" type="Spatial"] [node name="MeshInstance" type="MeshInstance" parent="."] -transform = Transform( 2.74393, 0, 0, 0, 1, 0, 0, 0, 4.27982, 0, -1.16203, 0 ) +transform = Transform( 2.74866, 0, 0, 0, 1.00172, 0, 0, 0, 13.5755, 0, -1.16203, 0 ) mesh = SubResource( 1 ) [node name="StaticBody" type="StaticBody" parent="MeshInstance"] @@ -27,5 +27,23 @@ mesh = SubResource( 1 ) [node name="CollisionShape" type="CollisionShape" parent="MeshInstance2/StaticBody"] shape = SubResource( 2 ) +[node name="MeshInstance3" type="MeshInstance" parent="."] +transform = Transform( 2.74393, 0, 0, 0, 1.89317, 0, 0, 0, 0.864162, 0, -1.16203, 5.22145 ) +mesh = SubResource( 1 ) + +[node name="StaticBody" type="StaticBody" parent="MeshInstance3"] + +[node name="CollisionShape" type="CollisionShape" parent="MeshInstance3/StaticBody"] +shape = SubResource( 2 ) + +[node name="MeshInstance4" type="MeshInstance" parent="."] +transform = Transform( 2.74393, 0, 0, 0, 1.89317, 0, 0, 0, 0.864162, 0, -0.269292, 7.68151 ) +mesh = SubResource( 1 ) + +[node name="StaticBody" type="StaticBody" parent="MeshInstance4"] + +[node name="CollisionShape" type="CollisionShape" parent="MeshInstance4/StaticBody"] +shape = SubResource( 2 ) + [node name="Player" parent="." instance=ExtResource( 1 )] transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.566872, 2.73697 ) diff --git a/godot/util.gd b/godot/util.gd index 53516ae..c919bb5 100644 --- a/godot/util.gd +++ b/godot/util.gd @@ -24,3 +24,10 @@ func activate_node(node: Node): node.set_process(true) node.set_physics_process(true) node.set_process_input(true) + +func clamped_lerp(src: float, dest: float, weight: float, close_enough: float): + weight = clamp(weight, 0.0, 1.0) + var v = lerp(src, dest, weight) + if abs(dest - v) < close_enough: + return dest + return v