rework StairStepper

This commit is contained in:
veclavtalica 2025-02-13 11:39:29 +03:00
parent cb48515d69
commit cda4b47ae9
3 changed files with 27 additions and 25 deletions

View File

@ -1,5 +1,4 @@
class_name Player extends CharacterBody3D
# TODO: inherit from StairStepper, not the other way around ? Probably by also having base Actor class.
const SPEED = 5.0
const JUMP_VELOCITY = 4.5
@ -92,7 +91,7 @@ func _physics_process(delta: float) -> void:
if velocity.length() > _max_speed:
velocity = velocity.clampf(0, _max_speed)
call("stair_step_up", direction)
$StairStepper.stair_step_up(direction)
if move_and_slide() and is_on_floor():
for idx in range(get_slide_collision_count()):
@ -103,7 +102,7 @@ func _physics_process(delta: float) -> void:
global_position = spawn_point.global_position
reset_physics_interpolation()
call("stair_step_down")
$StairStepper.stair_step_down()
@rpc("any_peer", "call_local", "reliable")

View File

@ -1,5 +1,6 @@
[gd_scene load_steps=8 format=3 uid="uid://cs8c570bxh6u"]
[gd_scene load_steps=9 format=3 uid="uid://cs8c570bxh6u"]
[ext_resource type="Script" path="res://src/ingame/player.gd" id="1_r8lgj"]
[ext_resource type="Script" path="res://src/lib/player_character.gd" id="1_sba4x"]
[ext_resource type="PackedScene" uid="uid://tdsbo3e5ic86" path="res://src/ingame/water_bomb.tscn" id="2_naek4"]
[ext_resource type="AudioStream" uid="uid://3dlhs18w1fa2" path="res://assets/sfx/boom.wav" id="3_u2hxa"]
@ -32,7 +33,7 @@ properties/5/replication_mode = 2
[node name="Player" type="CharacterBody3D" node_paths=PackedStringArray("_projectile_holder", "_projectile_point", "_camera_pivot", "_camera", "_line_of_sight", "_shot_sound")]
collision_layer = 2
script = ExtResource("1_sba4x")
script = ExtResource("1_r8lgj")
_projectile_scene = ExtResource("2_naek4")
_projectile_holder = NodePath("ProjectileHolder")
_projectile_point = NodePath("ProjectilePoint")
@ -41,6 +42,9 @@ _camera = NodePath("CameraPivot/Camera3D")
_line_of_sight = NodePath("CameraPivot/LineOfSight")
_shot_sound = NodePath("ShotSound")
[node name="StairStepper" type="Node" parent="."]
script = ExtResource("1_sba4x")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."]
replication_config = SubResource("SceneReplicationConfig_2xotl")

View File

@ -1,4 +1,4 @@
class_name StairStepper extends Player
class_name StairStepper extends Node
# MIT License
#
# Copyright (c) 2024 JKWall
@ -53,31 +53,30 @@ var was_grounded: bool = true
var is_grounded: bool = true
func _physics_process(delta: float) -> void:
func _physics_process(_delta: float) -> void:
was_grounded = is_grounded
is_grounded = is_on_floor()
super._physics_process(delta)
is_grounded = owner.is_on_floor()
# Function: Handle walking down stairs
func stair_step_down():
if is_on_floor():
if owner.is_on_floor():
return
# If we're falling from a step
if velocity.y <= 0 and was_grounded:
if owner.velocity.y <= 0 and was_grounded:
# Initialize body test variables
var body_test_result = PhysicsTestMotionResult3D.new()
var body_test_params = PhysicsTestMotionParameters3D.new()
body_test_params.from = self.global_transform ## We get the player's current global_transform
body_test_params.from = owner.global_transform ## We get the player's current global_transform
body_test_params.motion = Vector3(0, MAX_STEP_DOWN, 0) ## We project the player downward
if PhysicsServer3D.body_test_motion(self.get_rid(), body_test_params, body_test_result):
if PhysicsServer3D.body_test_motion(owner.get_rid(), body_test_params, body_test_result):
# Enters if a collision is detected by body_test_motion
# Get distance to step and move player downward by that much
position.y += body_test_result.get_travel().y
apply_floor_snap()
owner.position.y += body_test_result.get_travel().y
owner.apply_floor_snap()
is_grounded = true
@ -90,13 +89,13 @@ func stair_step_up(wish_dir: Vector3):
var body_test_params = PhysicsTestMotionParameters3D.new()
var body_test_result = PhysicsTestMotionResult3D.new()
var test_transform = global_transform ## Storing current global_transform for testing
var test_transform = owner.global_transform ## Storing current global_transform for testing
var distance = wish_dir * 0.1 ## Distance forward we want to check
body_test_params.from = self.global_transform ## Self as origin point
body_test_params.from = owner.global_transform ## Self as origin point
body_test_params.motion = distance ## Go forward by current distance
# Pre-check: Are we colliding?
if !PhysicsServer3D.body_test_motion(self.get_rid(), body_test_params, body_test_result):
if !PhysicsServer3D.body_test_motion(owner.get_rid(), body_test_params, body_test_result):
## If we don't collide, return
return
@ -108,13 +107,13 @@ func stair_step_up(wish_dir: Vector3):
var step_up = MAX_STEP_UP * Vector3.UP
body_test_params.from = test_transform
body_test_params.motion = step_up
PhysicsServer3D.body_test_motion(self.get_rid(), body_test_params, body_test_result)
PhysicsServer3D.body_test_motion(owner.get_rid(), body_test_params, body_test_result)
test_transform = test_transform.translated(body_test_result.get_travel())
# 3. Move test_transform forward by remaining distance
body_test_params.from = test_transform
body_test_params.motion = remainder
PhysicsServer3D.body_test_motion(self.get_rid(), body_test_params, body_test_result)
PhysicsServer3D.body_test_motion(owner.get_rid(), body_test_params, body_test_result)
test_transform = test_transform.translated(body_test_result.get_travel())
# 3.5 Project remaining along wall normal (if any)
@ -129,7 +128,7 @@ func stair_step_up(wish_dir: Vector3):
body_test_params.from = test_transform
body_test_params.motion = remainder * projected_vector
PhysicsServer3D.body_test_motion(self.get_rid(), body_test_params, body_test_result)
PhysicsServer3D.body_test_motion(owner.get_rid(), body_test_params, body_test_result)
test_transform = test_transform.translated(body_test_result.get_travel())
# 4. Move test_transform down onto step
@ -137,21 +136,21 @@ func stair_step_up(wish_dir: Vector3):
body_test_params.motion = MAX_STEP_UP * -Vector3.UP
# Return if no collision
if !PhysicsServer3D.body_test_motion(self.get_rid(), body_test_params, body_test_result):
if !PhysicsServer3D.body_test_motion(owner.get_rid(), body_test_params, body_test_result):
return
test_transform = test_transform.translated(body_test_result.get_travel())
# 5. Check floor normal for un-walkable slope
var surface_normal = body_test_result.get_collision_normal()
var temp_floor_max_angle = floor_max_angle + deg_to_rad(20)
var temp_floor_max_angle = owner.floor_max_angle + deg_to_rad(20)
if (snappedf(surface_normal.angle_to(Vector3.UP), 0.001) > temp_floor_max_angle):
return
# 6. Move player up
var global_pos = global_position
var global_pos = owner.global_position
#var step_up_dist = test_transform.origin.y - global_pos.y
global_pos.y = test_transform.origin.y
global_position = global_pos
owner.global_position = global_pos