ground sliding under stuff

This commit is contained in:
2026-01-14 15:26:41 +01:00
parent c6559d593a
commit ca77579168
7 changed files with 263 additions and 265 deletions

View File

@@ -506,6 +506,162 @@ use_collision = true
size = Vector3(5, 3, 2) size = Vector3(5, 3, 2)
material = ExtResource("3_vvhq3") material = ExtResource("3_vvhq3")
[node name="CSGBox3D38" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 21.5, 2.25, 22.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D39" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 21.25, 0.5, 22.5)
operation = 2
use_collision = true
size = Vector3(5, 3, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D40" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 28.5, 2.25, 22.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D41" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 28.25, 0.25, 22.5)
operation = 2
use_collision = true
size = Vector3(5, 2.5, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D42" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 35.5, 2.25, 22.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D43" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 35.25, -0.5, 22.5)
operation = 2
use_collision = true
size = Vector3(5, 3, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D44" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 42.5, 2.25, 22.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D45" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 42.25, -1, 22.5)
operation = 2
use_collision = true
size = Vector3(5, 3, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D46" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-2.6226834e-08, 0, -1, 0, 1, 0, 0.6, 0, -4.371139e-08, 21.5, 2.25, 31.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D47" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-2.6226834e-08, 0, -1, 0, 1, 0, 0.6, 0, -4.371139e-08, 21.25, 0.5, 31.5)
operation = 2
use_collision = true
size = Vector3(5, 3, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D48" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-2.6226834e-08, 0, -1, 0, 1, 0, 0.6, 0, -4.371139e-08, 28.5, 2.25, 31.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D49" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-2.6226834e-08, 0, -1, 0, 1, 0, 0.6, 0, -4.371139e-08, 28.25, 0.25, 31.5)
operation = 2
use_collision = true
size = Vector3(5, 2.5, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D50" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-2.6226834e-08, 0, -1, 0, 1, 0, 0.6, 0, -4.371139e-08, 35.5, 2.25, 31.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D51" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-2.6226834e-08, 0, -1, 0, 1, 0, 0.6, 0, -4.371139e-08, 35.25, -0.5, 31.5)
operation = 2
use_collision = true
size = Vector3(5, 3, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D52" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-2.6226834e-08, 0, -1, 0, 1, 0, 0.6, 0, -4.371139e-08, 42.5, 2.25, 31.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D53" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-2.6226834e-08, 0, -1, 0, 1, 0, 0.6, 0, -4.371139e-08, 42.25, -1, 31.5)
operation = 2
use_collision = true
size = Vector3(5, 3, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D54" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-7.86805e-09, 0, -1, 0, 1, 0, 0.18, 0, -4.371139e-08, 21.5, 2.25, 39.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D55" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-7.86805e-09, 0, -1, 0, 1, 0, 0.18, 0, -4.371139e-08, 21.25, 0.5, 39.5)
operation = 2
use_collision = true
size = Vector3(5, 3, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D56" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-7.86805e-09, 0, -1, 0, 1, 0, 0.18, 0, -4.371139e-08, 28.5, 2.25, 39.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D57" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-7.86805e-09, 0, -1, 0, 1, 0, 0.18, 0, -4.371139e-08, 28.25, 0.25, 39.5)
operation = 2
use_collision = true
size = Vector3(5, 2.5, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D58" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-7.86805e-09, 0, -1, 0, 1, 0, 0.18, 0, -4.371139e-08, 35.5, 2.25, 39.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D59" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-7.86805e-09, 0, -1, 0, 1, 0, 0.18, 0, -4.371139e-08, 35.25, -0.5, 39.5)
operation = 2
use_collision = true
size = Vector3(5, 3, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D60" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-7.86805e-09, 0, -1, 0, 1, 0, 0.18, 0, -4.371139e-08, 42.5, 2.25, 39.5)
use_collision = true
size = Vector3(5, 5, 5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D61" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(-7.86805e-09, 0, -1, 0, 1, 0, 0.18, 0, -4.371139e-08, 42.25, -1, 39.5)
operation = 2
use_collision = true
size = Vector3(5, 3, 1.5)
material = ExtResource("3_vvhq3")
[node name="CSGBox3D32" type="CSGBox3D" parent="Greybox/Passageways"] [node name="CSGBox3D32" type="CSGBox3D" parent="Greybox/Passageways"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, 2.25, -26.5) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 12, 2.25, -26.5)
use_collision = true use_collision = true

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=49 format=3 uid="uid://bei4nhkf8lwdo"] [gd_scene load_steps=50 format=3 uid="uid://bei4nhkf8lwdo"]
[ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"] [ext_resource type="Script" uid="uid://bbbrf5ckydfna" path="res://player_controller/Scripts/PlayerController.cs" id="1_poq2x"]
[ext_resource type="PackedScene" uid="uid://cf3rrgr1imvv4" path="res://scenes/path/path.tscn" id="2_6lejt"] [ext_resource type="PackedScene" uid="uid://cf3rrgr1imvv4" path="res://scenes/path/path.tscn" id="2_6lejt"]
@@ -11,7 +11,6 @@
[ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://systems/inputs/base_mode/move_front.tres" id="7_m8gvy"] [ext_resource type="Resource" uid="uid://brswsknpgwal2" path="res://systems/inputs/base_mode/move_front.tres" id="7_m8gvy"]
[ext_resource type="Resource" uid="uid://s1l0n1iitc6m" path="res://systems/inputs/base_mode/move_back.tres" id="8_jb43f"] [ext_resource type="Resource" uid="uid://s1l0n1iitc6m" path="res://systems/inputs/base_mode/move_back.tres" id="8_jb43f"]
[ext_resource type="Resource" uid="uid://j1o5ud0plk4" path="res://systems/inputs/base_mode/aim_release.tres" id="8_lhb11"] [ext_resource type="Resource" uid="uid://j1o5ud0plk4" path="res://systems/inputs/base_mode/aim_release.tres" id="8_lhb11"]
[ext_resource type="Script" uid="uid://dd1yrt7eiiyf4" path="res://player_controller/Scripts/CapsuleCollider.cs" id="8_lmtjd"]
[ext_resource type="Resource" uid="uid://c3e0ivgaxrsyb" path="res://systems/inputs/base_mode/aim_down.tres" id="8_obsfv"] [ext_resource type="Resource" uid="uid://c3e0ivgaxrsyb" path="res://systems/inputs/base_mode/aim_down.tres" id="8_obsfv"]
[ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://systems/mantle/mantle_system.tscn" id="8_qu4wy"] [ext_resource type="PackedScene" uid="uid://wq1okogkhc5l" path="res://systems/mantle/mantle_system.tscn" id="8_qu4wy"]
[ext_resource type="Resource" uid="uid://bebstkm608wxx" path="res://systems/inputs/base_mode/aim_pressed.tres" id="9_nob5r"] [ext_resource type="Resource" uid="uid://bebstkm608wxx" path="res://systems/inputs/base_mode/aim_pressed.tres" id="9_nob5r"]
@@ -47,6 +46,9 @@
[sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"] [sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"]
height = 1.7 height = 1.7
[sub_resource type="SphereShape3D" id="SphereShape3D_6lejt"]
radius = 0.45
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nodcl"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_nodcl"]
transparency = 1 transparency = 1
albedo_color = Color(0, 0.627451, 0.6313726, 0.49019608) albedo_color = Color(0, 0.627451, 0.6313726, 0.49019608)
@@ -61,6 +63,9 @@ height = 1.0
radius = 1.0 radius = 1.0
height = 3.5 height = 3.5
[sub_resource type="SphereShape3D" id="SphereShape3D_nob5r"]
radius = 0.4
[sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_2q0ik"] [sub_resource type="CanvasItemMaterial" id="CanvasItemMaterial_2q0ik"]
blend_mode = 1 blend_mode = 1
@@ -136,12 +141,16 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0)
visible = false visible = false
mesh = SubResource("CapsuleMesh_xc2g5") mesh = SubResource("CapsuleMesh_xc2g5")
[node name="CapsuleCollider" type="CollisionShape3D" parent="."] [node name="StandingCollider" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0)
shape = ExtResource("13_r7i3q") shape = ExtResource("13_r7i3q")
debug_color = Color(0, 0.6, 0.701961, 0.341176) debug_color = Color(0, 0.6, 0.701961, 0.341176)
script = ExtResource("8_lmtjd")
CapsuleDefaultHeight = 1.7 [node name="SlideCollider" type="CollisionShape3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.45, 0)
shape = SubResource("SphereShape3D_6lejt")
disabled = true
debug_color = Color(0, 0.6, 0.701961, 0.341176)
[node name="HeadSystem" parent="." instance=ExtResource("11_rxwoh")] [node name="HeadSystem" parent="." instance=ExtResource("11_rxwoh")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
@@ -251,6 +260,13 @@ mesh = SubResource("CylinderMesh_nodcl")
shape = SubResource("CapsuleShape3D_6lejt") shape = SubResource("CapsuleShape3D_6lejt")
collision_mask = 2 collision_mask = 2
[node name="CeilingDetector" type="ShapeCast3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.9, 0)
enabled = false
shape = SubResource("SphereShape3D_nob5r")
target_position = Vector3(0, 0.4, 0)
collision_mask = 2
[node name="DirectGroundDetector" type="RayCast3D" parent="."] [node name="DirectGroundDetector" type="RayCast3D" parent="."]
target_position = Vector3(0, -2, 0) target_position = Vector3(0, -2, 0)
collision_mask = 2 collision_mask = 2
@@ -550,6 +566,12 @@ delay_in_seconds = "0.0"
script = ExtResource("26_infe6") script = ExtResource("26_infe6")
initial_state = NodePath("SimpleJump") initial_state = NodePath("SimpleJump")
[node name="OnDash" type="Node" parent="StateChart/Root/Movement/Jump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Dashing/Dash")
event = &"dash"
delay_in_seconds = "0.0"
[node name="OnMantle" type="Node" parent="StateChart/Root/Movement/Jump"] [node name="OnMantle" type="Node" parent="StateChart/Root/Movement/Jump"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../Mantling") to = NodePath("../../Mantling")
@@ -590,6 +612,12 @@ delay_in_seconds = "0.0"
script = ExtResource("26_infe6") script = ExtResource("26_infe6")
initial_state = NodePath("Dash") initial_state = NodePath("Dash")
[node name="OnDashEndedGrounded" type="Node" parent="StateChart/Root/Movement/Dashing"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Grounded")
event = &"grounded"
delay_in_seconds = "0.0"
[node name="OnDashEnded" type="Node" parent="StateChart/Root/Movement/Dashing"] [node name="OnDashEnded" type="Node" parent="StateChart/Root/Movement/Dashing"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../Airborne/Reset") to = NodePath("../../Airborne/Reset")

View File

@@ -40,17 +40,13 @@ public partial class CapsuleCollider : CollisionShape3D
return Mathf.IsEqualApprox(_shape.Height, CapsuleCrouchHeight); return Mathf.IsEqualApprox(_shape.Height, CapsuleCrouchHeight);
} }
public void Crouch(float delta, float crouchTransitionSpeed) public void Crouch()
{ {
_shape.Height -= delta * crouchTransitionSpeed; _shape.Height = CapsuleCrouchHeight;
_shape.Height = Mathf.Clamp(_shape.Height, CapsuleCrouchHeight, CapsuleDefaultHeight);
} }
public void UndoCrouching(float delta, float crouchTransitionSpeed) public void Uncrouch()
{ {
_shape.Height += delta * crouchTransitionSpeed; _shape.Height = CapsuleDefaultHeight;
_shape.Height = Mathf.Clamp(_shape.Height, CapsuleCrouchHeight, CapsuleDefaultHeight);
} }
} }

View File

@@ -37,7 +37,8 @@ public partial class PlayerController : CharacterBody3D
public StairsSystem StairsSystem; public StairsSystem StairsSystem;
public MantleSystem MantleSystem; public MantleSystem MantleSystem;
public DashSystem DashSystem; public DashSystem DashSystem;
public CapsuleCollider CapsuleCollider; public CollisionShape3D StandingCollider;
public CollisionShape3D SlideCollider;
public Node3D WeaponRoot; public Node3D WeaponRoot;
public WeaponSystem WeaponSystem; public WeaponSystem WeaponSystem;
public WallHugSystem WallHugSystem; public WallHugSystem WallHugSystem;
@@ -49,6 +50,7 @@ public partial class PlayerController : CharacterBody3D
public CylinderMesh DashIndicatorMeshCylinder; public CylinderMesh DashIndicatorMeshCylinder;
public RayCast3D WallRunSnapper; public RayCast3D WallRunSnapper;
public ShapeCast3D GroundDetector; public ShapeCast3D GroundDetector;
public ShapeCast3D CeilingDetector;
public RayCast3D DirectGroundDetector; public RayCast3D DirectGroundDetector;
// Inspector stuff // Inspector stuff
@@ -330,12 +332,14 @@ public partial class PlayerController : CharacterBody3D
WeaponRoot = GetNode<Node3D>("WeaponRoot"); WeaponRoot = GetNode<Node3D>("WeaponRoot");
WeaponSystem = GetNode<WeaponSystem>("WeaponRoot/WeaponSystem"); WeaponSystem = GetNode<WeaponSystem>("WeaponRoot/WeaponSystem");
MantleSystem = GetNode<MantleSystem>("HeadSystem/MantleSystem"); MantleSystem = GetNode<MantleSystem>("HeadSystem/MantleSystem");
CapsuleCollider = GetNode<CapsuleCollider>("CapsuleCollider"); StandingCollider = GetNode<CollisionShape3D>("StandingCollider");
SlideCollider = GetNode<CollisionShape3D>("SlideCollider");
DashSystem = GetNode<DashSystem>("DashSystem"); DashSystem = GetNode<DashSystem>("DashSystem");
StairsSystem = GetNode<StairsSystem>("StairsSystem"); StairsSystem = GetNode<StairsSystem>("StairsSystem");
WallHugSystem = GetNode<WallHugSystem>("WallHugSystem"); WallHugSystem = GetNode<WallHugSystem>("WallHugSystem");
WallRunSnapper = GetNode<RayCast3D>("%WallRunSnapper"); WallRunSnapper = GetNode<RayCast3D>("%WallRunSnapper");
GroundDetector = GetNode<ShapeCast3D>("GroundDetector"); GroundDetector = GetNode<ShapeCast3D>("GroundDetector");
CeilingDetector = GetNode<ShapeCast3D>("CeilingDetector");
DirectGroundDetector = GetNode<RayCast3D>("DirectGroundDetector"); DirectGroundDetector = GetNode<RayCast3D>("DirectGroundDetector");
RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D"); RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D");
RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D"); RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D");
@@ -346,7 +350,7 @@ public partial class PlayerController : CharacterBody3D
"HeadCollisionDetectors/HeadCollisionDetector" + i); "HeadCollisionDetectors/HeadCollisionDetector" + i);
} }
var playerShape = CapsuleCollider.GetShape() as CapsuleShape3D; var playerShape = StandingCollider.GetShape() as CapsuleShape3D;
_playerHeight = playerShape!.Height; _playerHeight = playerShape!.Height;
_playerRadius = playerShape.Radius; _playerRadius = playerShape.Radius;
@@ -598,9 +602,9 @@ public partial class PlayerController : CharacterBody3D
StairsSystem.UpStairsCheckParams upStairsCheckParams = new StairsSystem.UpStairsCheckParams StairsSystem.UpStairsCheckParams upStairsCheckParams = new StairsSystem.UpStairsCheckParams
{ {
IsOnFloorCustom = isOnFloorCustom(), IsOnFloorCustom = isOnFloorCustom(),
IsCapsuleHeightLessThanNormal = CapsuleCollider.IsCapsuleHeightLessThanNormal(), IsCapsuleHeightLessThanNormal = false,
CurrentSpeedGreaterThanWalkSpeed = false, CurrentSpeedGreaterThanWalkSpeed = false,
IsCrouchingHeight = CapsuleCollider.IsCrouchingHeight(), IsCrouchingHeight = false,
Delta = delta, Delta = delta,
FloorMaxAngle = FloorMaxAngle, FloorMaxAngle = FloorMaxAngle,
GlobalPositionFromDriver = GlobalPosition, GlobalPositionFromDriver = GlobalPosition,
@@ -621,10 +625,10 @@ public partial class PlayerController : CharacterBody3D
StairsSystem.DownStairsCheckParams downStairsCheckParams = new StairsSystem.DownStairsCheckParams StairsSystem.DownStairsCheckParams downStairsCheckParams = new StairsSystem.DownStairsCheckParams
{ {
IsOnFloor = IsOnFloor(), IsOnFloor = IsOnFloor(),
IsCrouchingHeight = CapsuleCollider.IsCrouchingHeight(), IsCrouchingHeight = false,
LastFrameWasOnFloor = _lastFrameWasOnFloor, LastFrameWasOnFloor = _lastFrameWasOnFloor,
CapsuleDefaultHeight = CapsuleCollider.GetDefaultHeight(), CapsuleDefaultHeight = _playerHeight,
CurrentCapsuleHeight = CapsuleCollider.GetCurrentHeight(), CurrentCapsuleHeight = _playerHeight,
FloorMaxAngle = FloorMaxAngle, FloorMaxAngle = FloorMaxAngle,
VelocityY = Velocity.Y, VelocityY = Velocity.Y,
GlobalTransformFromDriver = GlobalTransform, GlobalTransformFromDriver = GlobalTransform,
@@ -642,9 +646,9 @@ public partial class PlayerController : CharacterBody3D
StairsSystem.SlideCameraParams slideCameraParams = new StairsSystem.SlideCameraParams StairsSystem.SlideCameraParams slideCameraParams = new StairsSystem.SlideCameraParams
{ {
IsCapsuleHeightLessThanNormal = CapsuleCollider.IsCapsuleHeightLessThanNormal(), IsCapsuleHeightLessThanNormal = false,
CurrentSpeedGreaterThanWalkSpeed = false, CurrentSpeedGreaterThanWalkSpeed = false,
BetweenCrouchingAndNormalHeight = CapsuleCollider.IsBetweenCrouchingAndNormalHeight(), BetweenCrouchingAndNormalHeight = false,
Delta = delta Delta = delta
}; };
StairsSystem.SlideCameraSmoothBackToOrigin(slideCameraParams); StairsSystem.SlideCameraSmoothBackToOrigin(slideCameraParams);
@@ -812,7 +816,7 @@ public partial class PlayerController : CharacterBody3D
FieldOfView.FovParameters fovParams = new FieldOfView.FovParameters FieldOfView.FovParameters fovParams = new FieldOfView.FovParameters
{ {
IsCrouchingHeight = CapsuleCollider.IsCrouchingHeight(), IsCrouchingHeight = false,
Delta = delta, Delta = delta,
SprintSpeed = WalkSpeed, SprintSpeed = WalkSpeed,
Velocity = Velocity, Velocity = Velocity,
@@ -943,7 +947,8 @@ public partial class PlayerController : CharacterBody3D
if (!_canDash) if (!_canDash)
{ {
_playerState.SendEvent("dash_finished"); var dashEvent = isOnFloorCustom() ? "grounded" : "dash_finished";
_playerState.SendEvent(dashEvent);
return; return;
} }
_canDash = false; _canDash = false;
@@ -961,7 +966,8 @@ public partial class PlayerController : CharacterBody3D
public void SimpleDashFinished() public void SimpleDashFinished()
{ {
_playerState.SendEvent("dash_finished"); var dashEvent = isOnFloorCustom() ? "grounded" : "dash_finished";
_playerState.SendEvent(dashEvent);
} }
/////////////////////////// ///////////////////////////
@@ -1256,13 +1262,18 @@ public partial class PlayerController : CharacterBody3D
/////////////////////////// ///////////////////////////
// Slide management // // Slide management //
/////////////////////////// ///////////////////////////
private bool _isSlideInputDown = false;
public void OnInputSlideStarted() public void OnInputSlideStarted()
{ {
_isSlideInputDown = true;
_playerState.SendEvent("slide"); _playerState.SendEvent("slide");
} }
public void OnInputSlideEnded() public void OnInputSlideEnded()
{ {
_playerState.SendEvent("slide_released"); _isSlideInputDown = false;
if (_airGliding.Active || CanStandUpFromSlide())
_playerState.SendEvent("slide_released");
} }
public record SlopeRecord( public record SlopeRecord(
@@ -1289,18 +1300,48 @@ public partial class PlayerController : CharacterBody3D
return new SlopeRecord(position, normal, direction, angle); return new SlopeRecord(position, normal, direction, angle);
} }
public void SetupSlideCollision()
{
StandingCollider.Disabled = true;
SlideCollider.Disabled = false;
CeilingDetector.Enabled = true;
}
public void SetupStandingCollision()
{
StandingCollider.Disabled = false;
SlideCollider.Disabled = true;
CeilingDetector.Enabled = false;
}
public void SlideStarted() public void SlideStarted()
{ {
_targetSpeed = Velocity.Length(); _targetSpeed = Velocity.Length();
SetupSlideCollision();
}
public bool CanStandUpFromSlide()
{
return !CeilingDetector.IsColliding();
}
public bool CanCancelSlide()
{
return DirectGroundDetector.IsColliding()
&& Velocity.Length() < WalkSpeed / 2f
&& CanStandUpFromSlide();
} }
public void SlideOnGround(float delta) public void SlideOnGround(float delta)
{ {
// Store current velocity // Store current velocity
var currentVelocity = Velocity.Length(); var currentVelocity = Velocity.Length();
var finalSpeed = currentVelocity * FlatGroundSlideSpeedLossRate; // We prevent automatically losing speed when sliding under something
var speedLossRate = CanStandUpFromSlide() ? FlatGroundSlideSpeedLossRate : 1.0f;
// We force a minimum of speed when sliding under something
var minimumVelocity = CanStandUpFromSlide() ? 0f : WalkSpeed;
var finalSpeed = Mathf.Max(currentVelocity * speedLossRate, minimumVelocity);
// Going down slope? // Going down a slope?
var (position, normal, slopeDirection, slopeAngleRadians) = GetSlope(); var (position, _, slopeDirection, slopeAngleRadians) = GetSlope();
// Change velocity based on Input // Change velocity based on Input
var horizontalVelocity = ComputeHVelocity(delta, AccelerationGroundSlide, DecelerationGroundSlide); var horizontalVelocity = ComputeHVelocity(delta, AccelerationGroundSlide, DecelerationGroundSlide);
@@ -1324,9 +1365,10 @@ public partial class PlayerController : CharacterBody3D
// redirectedVelocity = new Vector3(redirectedVelocity.X, redirectedVVelocity, redirectedVelocity.Z); // redirectedVelocity = new Vector3(redirectedVelocity.X, redirectedVVelocity, redirectedVelocity.Z);
// Moving upslope and not enough speed // Moving upslope and not enough speed
if (velocitySlopeAlignment < 0 && DirectGroundDetector.IsColliding() && Velocity.Length() < WalkSpeed / 2f) _playerState.SendEvent("slide_canceled"); if (velocitySlopeAlignment < 0 && CanCancelSlide())
_playerState.SendEvent("slide_canceled");
} }
else if (DirectGroundDetector.IsColliding() && Velocity.Length() < WalkSpeed / 2f) else if (CanCancelSlide())
{ {
// Moving on flat ground and not enough speed // Moving on flat ground and not enough speed
_playerState.SendEvent("slide_canceled"); _playerState.SendEvent("slide_canceled");
@@ -1340,9 +1382,9 @@ public partial class PlayerController : CharacterBody3D
GlobalPosition = new Vector3(GlobalPosition.X, position.Y, GlobalPosition.Z); GlobalPosition = new Vector3(GlobalPosition.X, position.Y, GlobalPosition.Z);
} }
} }
public void OnSlideCanceled() public void OnSlideCanceled()
{ {
SetupStandingCollision();
_targetSpeed = WalkSpeed; _targetSpeed = WalkSpeed;
} }
public void HandleSlideCanceled(float delta) public void HandleSlideCanceled(float delta)
@@ -1352,9 +1394,10 @@ public partial class PlayerController : CharacterBody3D
public void HandleGroundSlide(float delta) public void HandleGroundSlide(float delta)
{ {
SlideOnGround(delta); SlideOnGround(delta);
if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward()) _playerState.SendEvent("mantle"); if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward()) _playerState.SendEvent("mantle");
if (!isOnFloorCustom() && !DirectGroundDetector.IsColliding()) if (!isOnFloorCustom() && !DirectGroundDetector.IsColliding()) _playerState.SendEvent("start_falling");
_playerState.SendEvent("start_falling"); if (CanStandUpFromSlide() && !_isSlideInputDown) _playerState.SendEvent("slide_released");
} }
public void GlideInAir(float delta) public void GlideInAir(float delta)
@@ -1386,13 +1429,14 @@ public partial class PlayerController : CharacterBody3D
public void HandleAirGlide(float delta) public void HandleAirGlide(float delta)
{ {
GlideInAir(delta); GlideInAir(delta);
if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward()) _playerState.SendEvent("mantle");
if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward()) _playerState.SendEvent("mantle");
if (isOnFloorCustom()) if (isOnFloorCustom())
_playerState.SendEvent("grounded"); _playerState.SendEvent("grounded");
} }
public void SlideEnded() public void SlideEnded()
{ {
SetupStandingCollision();
_targetSpeed = WalkSpeed; _targetSpeed = WalkSpeed;
} }
@@ -1572,7 +1616,8 @@ public partial class PlayerController : CharacterBody3D
} }
public void AimedDashTweenEnded() public void AimedDashTweenEnded()
{ {
_playerState.SendEvent("dash_finished"); var dashEvent = isOnFloorCustom() ? "grounded" : "dash_finished";
_playerState.SendEvent(dashEvent);
} }
public void OnAimedDashFinished() public void OnAimedDashFinished()
{ {

View File

@@ -1,221 +0,0 @@
using Godot;
using Movementtests.player_controller.Scripts;
using RustyOptions;
namespace Movementtests.systems;
public partial class MoveSystem : Node3D
{
public enum JumpTypes
{
SimpleJump,
DoubleJump,
JumpFromDash,
JumpFromWall
}
public record MoveSystemParameters(
CharacterBody3D Parent,
Gravity Gravity,
MantleSystem MantleSystem,
TweenQueueSystem TweenQueueSystem,
HeadSystem HeadSystem,
CapsuleCollider CapsuleCollider);
public record MoveAroundParameters(
double Delta,
Vector3 MovementDirection,
bool IsOnFloor,
bool IsDead,
bool IsHeadTouchingCeiling,
bool isHanging,
bool isWallHugging
);
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
public float WalkSpeed { get; set; } = 5.0f;
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
public float SprintSpeed { get; set; } = 7.2f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float CrouchSpeed { get; set; } = 2.5f;
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
public float _currentSpeed;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float AccelerationSpeedFactorFloor = 5.0f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float DecelerationSpeedFactorFloor = 5.0f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float DecelerationSpeedFactorAir = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float ApexHoldTime = 0.0f;
private float _timeLeftAtApex = 0.0f;
private bool _wasGoingUpLastFrame = false;
public float CrouchTransitionSpeed { get; set; } = 20.0f;
[Export(PropertyHint.Range, "0,5,0.1,or_greater")]
public float WallHugGravityReducingFactor { get; set; } = 0.1f;
private Gravity _gravity;
private CharacterBody3D _parent;
private MantleSystem _mantleSystem;
private TweenQueueSystem _tweenQueueSystem;
private CapsuleCollider _capsuleCollider;
private HeadSystem _headSystem;
public void Init(MoveSystemParameters parameters)
{
_parent = parameters.Parent;
_gravity = parameters.Gravity;
_mantleSystem = parameters.MantleSystem;
_tweenQueueSystem = parameters.TweenQueueSystem;
_capsuleCollider = parameters.CapsuleCollider;
_headSystem = parameters.HeadSystem;
_currentSpeed = WalkSpeed;
}
private bool IsGoingUp()
{
return _parent.Velocity.Y > 0;
}
public void MoveAround(MoveAroundParameters param)
{
var (delta, movementDirection, isOnFloor, isDead, isHeadTouchingCeiling, isHanging, isWallHugging) = param;
var doesCapsuleHaveCrouchingHeight = _capsuleCollider.IsCrouchingHeight();
var doesCapsuleHaveDefaultHeight = _capsuleCollider.IsDefaultHeight();
if (IsGoingUp() || isOnFloor)
{
_wasGoingUpLastFrame = true;
_timeLeftAtApex = ApexHoldTime;
}
if (isHanging)
{
_parent.Velocity = Vector3.Zero;
_parent.MoveAndSlide();
return;
}
if (isWallHugging)
{
_parent.Velocity = new Vector3(
x: _parent.Velocity.X,
y: _parent.Velocity.Y - _gravity.CalculateGravityForce() * (float)delta * WallHugGravityReducingFactor,
z: _parent.Velocity.Z);
return;
}
// Adding the gravity
if (!isOnFloor)
{
if (!IsGoingUp() && _wasGoingUpLastFrame && _timeLeftAtApex > 0)
{
_parent.Velocity = new Vector3(
x: _parent.Velocity.X,
y: 0,
z: _parent.Velocity.Z);
_timeLeftAtApex -= (float) delta;
}
else
{
_parent.Velocity = new Vector3(
x: _parent.Velocity.X,
y: _parent.Velocity.Y - (_gravity.CalculateGravityForce() * (float)delta),
z: _parent.Velocity.Z);
}
}
// The code below is required to quickly adjust player's position on Y-axis when there's a ceiling on the
// trajectory of player's jump and player is standing
if (isHeadTouchingCeiling && doesCapsuleHaveDefaultHeight)
{
_parent.Velocity = new Vector3(
x: _parent.Velocity.X,
y: _parent.Velocity.Y - 2.0f,
z: _parent.Velocity.Z);
}
if (!isDead)
{
// Used both for detecting the moment when we enter into crouching mode and the moment when we're already
// in the crouching mode
if (Input.IsActionPressed("crouch") ||
(doesCapsuleHaveCrouchingHeight && isHeadTouchingCeiling))
{
_capsuleCollider.Crouch((float)delta, CrouchTransitionSpeed);
_currentSpeed = CrouchSpeed;
}
// Used both for the moment when we exit the crouching mode and for the moment when we just walk
else
{
_capsuleCollider.UndoCrouching((float)delta, CrouchTransitionSpeed);
_currentSpeed = WalkSpeed;
}
}
// Each component of the boolean statement for sprinting is required
if (Input.IsActionPressed("sprint") && !isHeadTouchingCeiling &&
!doesCapsuleHaveCrouchingHeight && !isDead)
{
_currentSpeed = SprintSpeed;
}
// Basis is a 3x4 matrix. It contains information about scaling and rotation of head.
// By multiplying our Vector3 by this matrix we're doing multiple things:
// a) We start to operate in global space;
// b) We're applying to Vector3 the current rotation of "head" object;
// c) We're applying to Vector3 the current scaling of "head" object;
Vector3 direction = _headSystem.Transform.Basis * movementDirection;
if (isDead)
{
direction = Vector3.Zero;
}
var accelerationFloorFactor = direction.Length() > 0 ? AccelerationSpeedFactorFloor : DecelerationSpeedFactorFloor;
var accelerationFactor = isOnFloor ? accelerationFloorFactor : DecelerationSpeedFactorAir;
float xAcceleration = Mathf.Lerp(_parent.Velocity.X, direction.X * _currentSpeed,
(float)delta * accelerationFactor);
float zAcceleration = Mathf.Lerp(_parent.Velocity.Z, direction.Z * _currentSpeed,
(float)delta * accelerationFactor);
_parent.Velocity = new Vector3(xAcceleration, _parent.Velocity.Y, zAcceleration);
if (isDead)
{
_parent.MoveAndSlide();
}
}
public void Jump(JumpTypes jumpType, Vector3? jumpDirection = null, float boost = 1.0f)
{
var effectiveJumpDirection = jumpDirection ?? Vector3.Up;
var jumpForce = 0.0f;
switch (jumpType)
{
case JumpTypes.DoubleJump:
jumpForce = _gravity.CalculateDoubleJumpForce();
break;
case JumpTypes.SimpleJump:
jumpForce = _gravity.CalculateJumpForce();
break;
case JumpTypes.JumpFromDash:
jumpForce = _gravity.CalculateJumpFromDashForce();
break;
case JumpTypes.JumpFromWall:
jumpForce = _gravity.CalculateJumpFromWallForce();
break;
default:
jumpForce = _gravity.CalculateJumpForce();
break;
}
var currentHorizontalVelocity = new Vector3(_parent.Velocity.X, 0, _parent.Velocity.Z);
var jumpVelocity = jumpForce * effectiveJumpDirection * boost;
_parent.Velocity = currentHorizontalVelocity + jumpVelocity;
}
}

View File

@@ -1 +0,0 @@
uid://dyy5njw6pxoh4

View File

@@ -1,5 +0,0 @@
[gd_resource type="Curve" format=3 uid="uid://buxwd3wd0nln5"]
[resource]
_data = [Vector2(0, 0), 0.0, 3.01651, 0, 0, Vector2(0.996169, 1), 0.0, 0.0, 0, 0]
point_count = 2