commit afbf7399343845fb50020cc0d739d4c982554c8b
parent befbf8bdbfe4ce523ee78f6ae6388981e7e101a2
Author: Yuval Langer <yuvallangerontheroad@gmail.com>
Date: Tue, 21 Sep 2021 21:24:38 +0300
Add four RayCast to the lower corners of the player to better detect the floor and avoid high gravity jittery bug.
Diffstat:
3 files changed, 53 insertions(+), 7 deletions(-)
diff --git a/Constants.gd b/Constants.gd
@@ -1,11 +1,14 @@
extends Node
+const on_floor_maximum_distance := 0.1
+
const road_box_dimensions: Vector3 = Vector3(0.35, 0.5, 0.95)
-const fall_acceleration: float = 0.5
-const jump_impulse: float = 7.0
+const fall_acceleration: float = 50.0
+const on_the_floor_fall_acceleration: float = 1.0
+const jump_impulse: float = 10.0
const maximum_forward_speed: float = 20.0
const forward_speed_increment: float = 0.5
const side_speed: float = 1.0
diff --git a/Player.gd b/Player.gd
@@ -1,10 +1,17 @@
extends KinematicBody
+onready var ray_cast1: RayCast = $RayCast1
+onready var ray_cast2: RayCast = $RayCast2
+onready var ray_cast3: RayCast = $RayCast3
+onready var ray_cast4: RayCast = $RayCast4
+
+
var velocity: Vector3 = Vector3.ZERO
var driving_speed: float = 0
var direction: int = 0
var last_pressed_direction: String = ""
+var on_floor_flag: bool = false
signal speed_changed
@@ -19,13 +26,27 @@ func _ready() -> void:
print_debug(forward_speed_change_timer.time_left)
+func is_near_floor(ray_cast: RayCast) -> bool:
+ if ray_cast.is_colliding():
+ var origin := ray_cast.global_transform.origin
+ var collision_point := ray_cast.get_collision_point()
+ var distance := origin.distance_to(collision_point)
+ return distance <= Constants.on_floor_maximum_distance
+ return false
+
+
func _physics_process(delta: float) -> void:
- var collision = move_and_collide(velocity, true, true, true)
+ var near_floor := (is_near_floor(ray_cast1)
+ or is_near_floor(ray_cast2)
+ or is_near_floor(ray_cast3)
+ or is_near_floor(ray_cast4))
+
+ var collision := move_and_collide(velocity, true, true, true)
if collision:
- var collider = collision.collider
+ var collider := collision.collider
if collider.is_in_group("goal"):
emit_signal("reached_goal")
- if is_on_floor():
+ if on_floor_flag:
direction = 0
if (
(not Input.is_action_just_pressed("ui_right")) or
@@ -78,9 +99,15 @@ func _physics_process(delta: float) -> void:
velocity.x = direction * Constants.side_speed
velocity.z = -driving_speed
- if is_on_floor() and Input.is_action_just_pressed("jump"):
+ if is_on_floor():
+ on_floor_flag = true
+ if on_floor_flag and Input.is_action_just_pressed("jump"):
velocity.y += Constants.jump_impulse
- velocity.y -= Constants.fall_acceleration
+ on_floor_flag = false
+ if near_floor:
+ velocity.y -= Constants.on_the_floor_fall_acceleration * delta
+ else:
+ velocity.y -= Constants.fall_acceleration * delta
velocity = move_and_slide(velocity, Vector3.UP)
diff --git a/Player.tscn b/Player.tscn
@@ -24,3 +24,19 @@ shape = SubResource( 2 )
[node name="ForwardSpeedChangeTimer" type="Timer" parent="."]
wait_time = 0.2
one_shot = true
+
+[node name="RayCast1" type="RayCast" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.125, -0.075, 0.15 )
+enabled = true
+
+[node name="RayCast2" type="RayCast" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.125, -0.075, 0.15 )
+enabled = true
+
+[node name="RayCast3" type="RayCast" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.125, -0.075, -0.15 )
+enabled = true
+
+[node name="RayCast4" type="RayCast" parent="."]
+transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -0.125, -0.075, -0.15 )
+enabled = true