diff --git a/maps/GYMs/metrics.tscn b/maps/GYMs/metrics.tscn index abfbf3e2..517dbf65 100644 --- a/maps/GYMs/metrics.tscn +++ b/maps/GYMs/metrics.tscn @@ -133,6 +133,21 @@ material = ExtResource("3_vvhq3") transform = Transform3D(5, 0, 0, 0, -2.18557e-07, 5, 0, -5, -2.18557e-07, 1, 0.1, -9.5) text = "10m" +[node name="Label3D6" type="Label3D" parent="Greybox/RunningTrack"] +transform = Transform3D(5, 0, 0, 0, -2.18557e-07, 5, 0, -5, -2.18557e-07, 27.5, 0.1, 1) +text = "10deg +" + +[node name="Label3D7" type="Label3D" parent="Greybox/RunningTrack"] +transform = Transform3D(5, 0, 0, 0, -2.18557e-07, 5, 0, -5, -2.18557e-07, 30.5, 0.1, 1) +text = "20deg +" + +[node name="Label3D8" type="Label3D" parent="Greybox/RunningTrack"] +transform = Transform3D(5, 0, 0, 0, -2.18557e-07, 5, 0, -5, -2.18557e-07, 33.5, 0.1, 1) +text = "30deg +" + [node name="Label3D2" type="Label3D" parent="Greybox/RunningTrack"] transform = Transform3D(5, 0, 0, 0, -2.18557e-07, 5, 0, -5, -2.18557e-07, 1, 0.1, -19.5) text = "20m" @@ -367,6 +382,60 @@ use_collision = true size = Vector3(7.5, 20, 10) material = ExtResource("3_vvhq3") +[node name="CSGBox3D41" type="CSGBox3D" parent="Greybox/JumpHeights"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 22.75, 5, -1.5) +use_collision = true +size = Vector3(12.5, 10, 3) +material = ExtResource("3_vvhq3") + +[node name="CSGBox3D47" type="CSGBox3D" parent="Greybox/JumpHeights"] +transform = Transform3D(1, 0, 0, 0, 0.9848078, 0.17364816, 0, -0.17364816, 0.9848078, 22.75, 0.03095889, -30.695885) +use_collision = true +size = Vector3(12.5, 10, 58) +material = ExtResource("3_vvhq3") + +[node name="CSGBox3D48" type="CSGBox3D" parent="Greybox/JumpHeights"] +transform = Transform3D(1, 0, 0, 0, 0.9396926, 0.34202012, 0, -0.34202012, 0.9396926, 30.5, 1.5878377, -16.713436) +use_collision = true +size = Vector3(3, 6.5, 31.5) +material = ExtResource("3_vvhq3") + +[node name="CSGBox3D49" type="CSGBox3D" parent="Greybox/JumpHeights"] +transform = Transform3D(1, 0, 0, 0, 0.86602545, 0.5, 0, -0.5, 0.86602545, 33.5, 2.5053406, -10.524445) +use_collision = true +size = Vector3(3, 5.5, 20.5) +material = ExtResource("3_vvhq3") + +[node name="CSGBox3D42" type="CSGBox3D" parent="Greybox/JumpHeights"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 30.5, 5, -1.5) +use_collision = true +size = Vector3(3, 10, 3) +material = ExtResource("3_vvhq3") + +[node name="CSGBox3D43" type="CSGBox3D" parent="Greybox/JumpHeights"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 33.5, 5, -1.5) +use_collision = true +size = Vector3(3, 10, 3) +material = ExtResource("3_vvhq3") + +[node name="CSGBox3D44" type="CSGBox3D" parent="Greybox/JumpHeights"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 36.5, 5, -1.5) +use_collision = true +size = Vector3(3, 10, 3) +material = ExtResource("3_vvhq3") + +[node name="CSGBox3D45" type="CSGBox3D" parent="Greybox/JumpHeights"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 39.5, 5, -1.5) +use_collision = true +size = Vector3(3, 10, 3) +material = ExtResource("3_vvhq3") + +[node name="CSGBox3D46" type="CSGBox3D" parent="Greybox/JumpHeights"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 42.5, 5, -1.5) +use_collision = true +size = Vector3(3, 10, 3) +material = ExtResource("3_vvhq3") + [node name="CSGBox3D34" type="CSGBox3D" parent="Greybox/JumpHeights"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -24.5, 10, -15) use_collision = true diff --git a/player_controller/PlayerController.tscn b/player_controller/PlayerController.tscn index c513ea18..761fc962 100644 --- a/player_controller/PlayerController.tscn +++ b/player_controller/PlayerController.tscn @@ -91,6 +91,8 @@ PostDashSpeed = 30.0 SlamSpeed = 80.0 GroundSlideJumpMultiplier = 0.1 GroundSlideJumpSpeedFactor = 0.1 +GroundSlideDownSlopeAcceleration = 0.2 +GroundSlideDownSlopeMaxSpeed = 30.0 AirGlideVSpeed = 4.0 AccelerationAirGlide = 0.4 AirGlideVerticalAcceleration = 8.0 diff --git a/player_controller/Scripts/PlayerController.cs b/player_controller/Scripts/PlayerController.cs index a5549052..fbd7a7cd 100644 --- a/player_controller/Scripts/PlayerController.cs +++ b/player_controller/Scripts/PlayerController.cs @@ -146,6 +146,13 @@ public partial class PlayerController : CharacterBody3D public float GroundSlideJumpMultiplier = 1.0f; [Export(PropertyHint.Range, "0,1,0.01,or_greater")] public float GroundSlideJumpSpeedFactor; + [Export(PropertyHint.Range, "0,1,0.01,or_greater")] + public float GroundSlideDownSlopeAcceleration = 0.1f; + [Export(PropertyHint.Range, "0,100,0.1,or_greater")] + public float GroundSlideDownSlopeMaxSpeed = 50f; + [Export(PropertyHint.Range, "1,10,0.1,or_greater")] + public float GroundSlideSlopeMagnetism = 2f; + [ExportSubgroup("Air glide")] [Export] @@ -265,6 +272,7 @@ public partial class PlayerController : CharacterBody3D private StateChartState _grounded; private StateChartState _airborne; private StateChartState _coyoteEnabled; + private StateChartState _jumping; private StateChartState _simpleJump; private StateChartState _doubleJump; private StateChartState _mantling; @@ -361,6 +369,7 @@ public partial class PlayerController : CharacterBody3D _airborne = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne")); _coyoteEnabled = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne/CoyoteEnabled")); // _doubleJumpEnabled = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne/DoubleJumpEnabled")); + _jumping = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump")); _simpleJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/SimpleJump")); _doubleJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/DoubleJump")); _mantling = StateChartState.Of(GetNode("StateChart/Root/Movement/Mantling")); @@ -593,7 +602,7 @@ public partial class PlayerController : CharacterBody3D }; StairsSystem.UpStairsCheckResult upStairsCheckResult = StairsSystem.SnapUpStairsCheck(upStairsCheckParams); - if (upStairsCheckResult.UpdateRequired) + if (upStairsCheckResult.UpdateRequired && !_jumping.Active) { upStairsCheckResult.Update(this); } @@ -1092,7 +1101,9 @@ public partial class PlayerController : CharacterBody3D public void OnJumpStarted(float verticalVelocity) { _framesSinceJumpAtApex = 0; - SetVerticalVelocity(verticalVelocity*_jumpStrengthMultiplier); + var angle = GetFloorAngle(); + var floorAngleFactor = angle > 1 ? 1 : 1 + angle; + SetVerticalVelocity(verticalVelocity*_jumpStrengthMultiplier*floorAngleFactor); _jumpStrengthMultiplier = 1.0f; } public void OnSimpleJumpStarted() @@ -1246,24 +1257,70 @@ public partial class PlayerController : CharacterBody3D _playerState.SendEvent("slide_released"); } + public record SlopeRecord( + Vector3 Position, + Vector3 Normal, + Vector3 Direction, + float AngleRadians + ); + public Vector3 GetGroundPosition() + { + return GroundDetector.GetCollisionPoint(0); + } + public Vector3 GetGroundNormal() + { + return GroundDetector.GetCollisionNormal(0); + } + public SlopeRecord GetSlope() + { + var position = GetGroundPosition(); + var normal = GetGroundNormal(); + var angle = normal.AngleTo(Vector3.Up); + var vectorInPlane = normal.Cross(Vector3.Up).Normalized(); + var direction = normal.Cross(vectorInPlane).Normalized(); + return new SlopeRecord(position, normal, direction, angle); + } + public void SlideStarted() { _targetSpeed = Velocity.Length(); } public void SlideOnGround(float delta) { + // Store current velocity var currentVelocity = Velocity.Length(); + + // Going down slope? + var (position, normal, slopeDirection, slopeAngleRadians) = GetSlope(); + + // Change velocity based on Input var horizontalVelocity = ComputeHVelocity(delta, AccelerationGroundSlide, DecelerationGroundSlide); - var newVelocity = new Vector3(horizontalVelocity.X, Velocity.Y, horizontalVelocity.Z); - Velocity = newVelocity.Normalized() * currentVelocity; // prevent from losing momentum + var newVelocityDirection = new Vector3(horizontalVelocity.X, 0, horizontalVelocity.Z).Normalized(); + // var redirectedVelocity = newVelocityDirection.Slide(normal); + + var redirectedVelocity = newVelocityDirection; + var speedFactorFromDownSlope = 1f; + if (slopeAngleRadians > Mathf.Epsilon) + { + var slopeHDirection = new Vector3(slopeDirection.X, 0, slopeDirection.Z); + redirectedVelocity = newVelocityDirection.Lerp(slopeHDirection, delta * GroundSlideSlopeMagnetism); + + var angleBetweenVelocityAndSlope = redirectedVelocity.AngleTo(slopeHDirection); + var cosAngle = Mathf.Cos(angleBetweenVelocityAndSlope); + var redirectedVVelocity = slopeDirection.Y * cosAngle; + + redirectedVelocity = new Vector3(redirectedVelocity.X, redirectedVVelocity, redirectedVelocity.Z); + speedFactorFromDownSlope = Velocity.Length() > GroundSlideDownSlopeMaxSpeed ? 1f : 1f + GroundSlideDownSlopeAcceleration * GetFloorAngle() * cosAngle; + } + + // Preserve velocity when changing direction + var finalVelocity = redirectedVelocity.Normalized() * currentVelocity * speedFactorFromDownSlope; + Velocity = finalVelocity; } public void HandleGroundSlide(float delta) { - // GD.Print(GetFloorAngle()); - SlideOnGround(delta); if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward()) _playerState.SendEvent("mantle"); - if (!isOnFloorCustom()) _playerState.SendEvent("start_falling"); } @@ -1593,6 +1650,4 @@ public partial class PlayerController : CharacterBody3D DashIndicatorNode.LookAt(WeaponSystem.GlobalPosition); } } - - } diff --git a/systems/wall_hug/WallHugSystem.cs b/systems/wall_hug/WallHugSystem.cs index bf056aba..f140fbc1 100644 --- a/systems/wall_hug/WallHugSystem.cs +++ b/systems/wall_hug/WallHugSystem.cs @@ -40,7 +40,7 @@ public partial class WallHugSystem : Node3D { foreach (RayCast3D raycast in _raycasts) { - if (raycast.IsColliding()) + if (raycast.IsColliding() && Math.Abs(raycast.GetCollisionNormal().Y) < 0.3f) { WallHugLocation = raycast.GetCollisionPoint().Some(); WallHugNormal = raycast.GetCollisionNormal().Some();