jumping from slides and some improvement on air gliding

This commit is contained in:
2026-01-13 14:22:26 +01:00
parent 2fa4ce68e7
commit 30b4d1a2eb
2 changed files with 140 additions and 29 deletions

View File

@@ -89,9 +89,13 @@ SimpleDashTime = 0.2
AimedDashTime = 0.2 AimedDashTime = 0.2
PostDashSpeed = 30.0 PostDashSpeed = 30.0
SlamSpeed = 80.0 SlamSpeed = 80.0
AccelerationGroundSlide = 0.2 GroundSlideJumpMultiplier = 0.1
GroundSlideJumpSpeedFactor = 0.1
AirGlideVSpeed = 4.0 AirGlideVSpeed = 4.0
AccelerationAirGlide = 0.2 AccelerationAirGlide = 0.4
AirGlideVerticalAcceleration = 8.0
AirGlideJumpMultiplier = 0.1
AirGlideJumpSpeedFactor = 0.05
WallHugGravityLesseningFactor = 15.0 WallHugGravityLesseningFactor = 15.0
WallHugDownwardMaxSpeed = 4.0 WallHugDownwardMaxSpeed = 4.0
WallHugHorizontalDeceleration = 1.0 WallHugHorizontalDeceleration = 1.0
@@ -540,12 +544,6 @@ delay_in_seconds = "0.0"
script = ExtResource("26_infe6") script = ExtResource("26_infe6")
initial_state = NodePath("SimpleJump") initial_state = NodePath("SimpleJump")
[node name="OnSlide" type="Node" parent="StateChart/Root/Movement/Jump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Sliding/AirGlide")
event = &"slide"
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")
@@ -561,6 +559,12 @@ to = NodePath("../../../Airborne/DoubleJumpEnabled")
event = &"jump_ended" event = &"jump_ended"
delay_in_seconds = "0.0" delay_in_seconds = "0.0"
[node name="OnSlide" type="Node" parent="StateChart/Root/Movement/Jump/SimpleJump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Sliding/AirGlideDoubleJumpEnabled")
event = &"slide"
delay_in_seconds = "0.0"
[node name="DoubleJump" type="Node" parent="StateChart/Root/Movement/Jump"] [node name="DoubleJump" type="Node" parent="StateChart/Root/Movement/Jump"]
script = ExtResource("27_34snm") script = ExtResource("27_34snm")
@@ -570,6 +574,12 @@ to = NodePath("../../../Airborne/Falling")
event = &"jump_ended" event = &"jump_ended"
delay_in_seconds = "0.0" delay_in_seconds = "0.0"
[node name="OnSlide" type="Node" parent="StateChart/Root/Movement/Jump/DoubleJump"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Sliding/AirGlide")
event = &"slide"
delay_in_seconds = "0.0"
[node name="Dashing" type="Node" parent="StateChart/Root/Movement"] [node name="Dashing" type="Node" parent="StateChart/Root/Movement"]
script = ExtResource("26_infe6") script = ExtResource("26_infe6")
initial_state = NodePath("Dash") initial_state = NodePath("Dash")
@@ -602,6 +612,12 @@ script = ExtResource("27_34snm")
script = ExtResource("26_infe6") script = ExtResource("26_infe6")
initial_state = NodePath("GroundSlide") initial_state = NodePath("GroundSlide")
[node name="OnDash" type="Node" parent="StateChart/Root/Movement/Sliding"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Dashing/Dash")
event = &"actually_no_dash"
delay_in_seconds = "0.0"
[node name="OnMantle" type="Node" parent="StateChart/Root/Movement/Sliding"] [node name="OnMantle" type="Node" parent="StateChart/Root/Movement/Sliding"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../Mantling") to = NodePath("../../Mantling")
@@ -619,10 +635,37 @@ delay_in_seconds = "0.0"
[node name="OnAirborne" type="Node" parent="StateChart/Root/Movement/Sliding/GroundSlide"] [node name="OnAirborne" type="Node" parent="StateChart/Root/Movement/Sliding/GroundSlide"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../AirGlide") to = NodePath("../../AirGlideDoubleJumpEnabled")
event = &"start_falling" event = &"start_falling"
delay_in_seconds = "0.0" delay_in_seconds = "0.0"
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/Sliding/GroundSlide"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/SimpleJump")
event = &"jump"
delay_in_seconds = "0.0"
[node name="AirGlideDoubleJumpEnabled" type="Node" parent="StateChart/Root/Movement/Sliding"]
script = ExtResource("27_34snm")
[node name="OnSlideReleased" type="Node" parent="StateChart/Root/Movement/Sliding/AirGlideDoubleJumpEnabled"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Airborne/Reset")
event = &"slide_released"
delay_in_seconds = "0.0"
[node name="OnGrounded" type="Node" parent="StateChart/Root/Movement/Sliding/AirGlideDoubleJumpEnabled"]
script = ExtResource("28_n7qhm")
to = NodePath("../../GroundSlide")
event = &"grounded"
delay_in_seconds = "0.0"
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/Sliding/AirGlideDoubleJumpEnabled"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/DoubleJump")
event = &"jump"
delay_in_seconds = "0.0"
[node name="AirGlide" type="Node" parent="StateChart/Root/Movement/Sliding"] [node name="AirGlide" type="Node" parent="StateChart/Root/Movement/Sliding"]
script = ExtResource("27_34snm") script = ExtResource("27_34snm")
@@ -664,12 +707,6 @@ to = NodePath("../../Grounded")
event = &"grounded" event = &"grounded"
delay_in_seconds = "0.0" delay_in_seconds = "0.0"
[node name="OnSlide" type="Node" parent="StateChart/Root/Movement/Airborne"]
script = ExtResource("28_n7qhm")
to = NodePath("../../Sliding/AirGlide")
event = &"slide"
delay_in_seconds = "0.0"
[node name="OnSlam" type="Node" parent="StateChart/Root/Movement/Airborne"] [node name="OnSlam" type="Node" parent="StateChart/Root/Movement/Airborne"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../Slamming") to = NodePath("../../Slamming")
@@ -679,6 +716,12 @@ delay_in_seconds = "0.0"
[node name="CoyoteEnabled" type="Node" parent="StateChart/Root/Movement/Airborne"] [node name="CoyoteEnabled" type="Node" parent="StateChart/Root/Movement/Airborne"]
script = ExtResource("27_34snm") script = ExtResource("27_34snm")
[node name="OnSlide" type="Node" parent="StateChart/Root/Movement/Airborne/CoyoteEnabled"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Sliding/AirGlideDoubleJumpEnabled")
event = &"slide"
delay_in_seconds = "0.0"
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/Airborne/CoyoteEnabled"] [node name="OnJump" type="Node" parent="StateChart/Root/Movement/Airborne/CoyoteEnabled"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/SimpleJump") to = NodePath("../../../Jump/SimpleJump")
@@ -694,6 +737,12 @@ delay_in_seconds = "0.0"
[node name="DoubleJumpEnabled" type="Node" parent="StateChart/Root/Movement/Airborne"] [node name="DoubleJumpEnabled" type="Node" parent="StateChart/Root/Movement/Airborne"]
script = ExtResource("27_34snm") script = ExtResource("27_34snm")
[node name="OnSlide" type="Node" parent="StateChart/Root/Movement/Airborne/DoubleJumpEnabled"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Sliding/AirGlideDoubleJumpEnabled")
event = &"slide"
delay_in_seconds = "0.0"
[node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne/DoubleJumpEnabled"] [node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne/DoubleJumpEnabled"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../../OnWall/Hugging") to = NodePath("../../../OnWall/Hugging")
@@ -709,6 +758,12 @@ delay_in_seconds = "0.0"
[node name="Falling" type="Node" parent="StateChart/Root/Movement/Airborne"] [node name="Falling" type="Node" parent="StateChart/Root/Movement/Airborne"]
script = ExtResource("27_34snm") script = ExtResource("27_34snm")
[node name="OnSlide" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"]
script = ExtResource("28_n7qhm")
to = NodePath("../../../Sliding/AirGlide")
event = &"slide"
delay_in_seconds = "0.0"
[node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"] [node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../../OnWall/Hugging") to = NodePath("../../../OnWall/Hugging")

View File

@@ -142,14 +142,27 @@ public partial class PlayerController : CharacterBody3D
public float AccelerationGroundSlide = 1.0f; public float AccelerationGroundSlide = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")] [Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float DecelerationGroundSlide = 0.1f; public float DecelerationGroundSlide = 0.1f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float GroundSlideJumpMultiplier = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float GroundSlideJumpSpeedFactor;
[ExportSubgroup("Air glide")] [ExportSubgroup("Air glide")]
[Export]
public bool AllowForVelocityRedirection = true;
[Export(PropertyHint.Range, "0,10,0.01,or_greater")] [Export(PropertyHint.Range, "0,10,0.01,or_greater")]
public float AirGlideVSpeed { get; set; } = 1.0f; public float AirGlideVSpeed { get; set; } = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")] [Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float AccelerationAirGlide = 1.0f; public float AccelerationAirGlide = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")] [Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float DecelerationAirGlide = 0.1f; public float DecelerationAirGlide = 0.1f;
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
public float AirGlideVerticalAcceleration = 1.0f;
[Export(PropertyHint.Range, "0,10,0.1,or_greater")]
public float AirGlideJumpMultiplier = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float AirGlideJumpSpeedFactor;
// Wall hug // Wall hug
[ExportGroup("Wall hug")] [ExportGroup("Wall hug")]
@@ -260,6 +273,7 @@ public partial class PlayerController : CharacterBody3D
private StateChartState _sliding; private StateChartState _sliding;
private StateChartState _groundSliding; private StateChartState _groundSliding;
private StateChartState _airGliding; private StateChartState _airGliding;
private StateChartState _airGlidingDoubleJump;
private StateChartState _slamming; private StateChartState _slamming;
private StateChartState _onWall; private StateChartState _onWall;
private StateChartState _onWallHugging; private StateChartState _onWallHugging;
@@ -269,6 +283,9 @@ public partial class PlayerController : CharacterBody3D
private Transition _onJumpFromWall; private Transition _onJumpFromWall;
private Transition _onJumpFromWallFalling; private Transition _onJumpFromWallFalling;
private Transition _onLeaveWallFromRun; private Transition _onLeaveWallFromRun;
private Transition _onGroundSlideJump;
private Transition _onAirGlideDoubleJump;
public override void _Ready() public override void _Ready()
{ {
@@ -326,11 +343,14 @@ public partial class PlayerController : CharacterBody3D
_aiming = StateChartState.Of(GetNode("StateChart/Root/Aim/On")); _aiming = StateChartState.Of(GetNode("StateChart/Root/Aim/On"));
_simpleDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/Dash")); _simpleDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/Dash"));
_aimedDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/AimedDash")); _aimedDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/AimedDash"));
_slamming = StateChartState.Of(GetNode("StateChart/Root/Movement/Slamming"));
_sliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding")); _sliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding"));
_groundSliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/GroundSlide")); _groundSliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/GroundSlide"));
_airGliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/AirGlide")); _airGliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/AirGlide"));
_slamming = StateChartState.Of(GetNode("StateChart/Root/Movement/Slamming")); _airGlidingDoubleJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/AirGlideDoubleJumpEnabled"));
_onGroundSlideJump = Transition.Of(GetNode("StateChart/Root/Movement/Sliding/GroundSlide/OnJump"));
_onAirGlideDoubleJump = Transition.Of(GetNode("StateChart/Root/Movement/Sliding/AirGlideDoubleJumpEnabled/OnJump"));
// _actionHanging = StateChartState.Of(GetNode("StateChart/Root/Actions/Hanging")); // _actionHanging = StateChartState.Of(GetNode("StateChart/Root/Actions/Hanging"));
_powerExpired = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Expired")); _powerExpired = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Expired"));
@@ -423,6 +443,10 @@ public partial class PlayerController : CharacterBody3D
_sliding.StateExited += SlideEnded; _sliding.StateExited += SlideEnded;
_groundSliding.StatePhysicsProcessing += HandleGroundSlide; _groundSliding.StatePhysicsProcessing += HandleGroundSlide;
_airGliding.StatePhysicsProcessing += HandleAirGlide; _airGliding.StatePhysicsProcessing += HandleAirGlide;
_airGlidingDoubleJump.StatePhysicsProcessing += HandleAirGlide;
_onGroundSlideJump.Taken += JumpFromGroundSlide;
_onAirGlideDoubleJump.Taken += JumpFromAirGlide;
_slamming.StateEntered += SlamStarted; _slamming.StateEntered += SlamStarted;
_slamming.StateExited += SlamEnded; _slamming.StateExited += SlamEnded;
@@ -1063,11 +1087,13 @@ public partial class PlayerController : CharacterBody3D
} }
_playerState.SendEvent("jump"); _playerState.SendEvent("jump");
} }
private float _jumpStrengthMultiplier = 1.0f;
public void OnJumpStarted(float verticalVelocity) public void OnJumpStarted(float verticalVelocity)
{ {
_framesSinceJumpAtApex = 0; _framesSinceJumpAtApex = 0;
SetVerticalVelocity(verticalVelocity); SetVerticalVelocity(verticalVelocity*_jumpStrengthMultiplier);
_jumpStrengthMultiplier = 1.0f;
} }
public void OnSimpleJumpStarted() public void OnSimpleJumpStarted()
{ {
@@ -1201,7 +1227,7 @@ public partial class PlayerController : CharacterBody3D
var positionDifference = GlobalPosition - _mantleStartPosition; var positionDifference = GlobalPosition - _mantleStartPosition;
var directionHorizontal = new Vector3(positionDifference.X, 0, positionDifference.Z); var directionHorizontal = new Vector3(positionDifference.X, 0, positionDifference.Z);
// SimpleDashInDirection(directionHorizontal.Normalized()); // SimpleDashInDirection(directionHorizontal.Normalized());
SetVelocity(directionHorizontal.Normalized() * WalkSpeed); SetVelocity(directionHorizontal.Normalized() * _velocityOnMantleStarted.Length());
} }
_customMantle = false; _customMantle = false;
@@ -1226,27 +1252,47 @@ public partial class PlayerController : CharacterBody3D
} }
public void SlideOnGround(float delta) public void SlideOnGround(float delta)
{ {
var currentVelocity = Velocity.Length();
var horizontalVelocity = ComputeHVelocity(delta, AccelerationGroundSlide, DecelerationGroundSlide); var horizontalVelocity = ComputeHVelocity(delta, AccelerationGroundSlide, DecelerationGroundSlide);
Velocity = new Vector3(horizontalVelocity.X, Velocity.Y, horizontalVelocity.Z); var newVelocity = new Vector3(horizontalVelocity.X, Velocity.Y, horizontalVelocity.Z);
Velocity = newVelocity.Normalized() * currentVelocity; // prevent from losing momentum
} }
public void HandleGroundSlide(float delta) public void HandleGroundSlide(float delta)
{ {
// GD.Print(GetFloorAngle());
SlideOnGround(delta); SlideOnGround(delta);
if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward()) _playerState.SendEvent("mantle"); if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward()) _playerState.SendEvent("mantle");
if (!isOnFloorCustom()) if (!isOnFloorCustom())
_playerState.SendEvent("start_falling"); _playerState.SendEvent("start_falling");
} }
public void GlideInAir(float delta) public void GlideInAir(float delta)
{ {
var horizontalVelocity = ComputeHVelocity(delta, AccelerationAirGlide, DecelerationAirGlide); if (AllowForVelocityRedirection)
{
float verticalSpeed; // Preserve overall velocity
if (Velocity.Y < -AirGlideVSpeed) verticalSpeed = -AirGlideVSpeed; // Allows for tragic reorientation of the velocity vector after a fall
else if (Velocity.Y > 0) verticalSpeed = ComputeVerticalSpeedGravity(delta); // Allows for bunny-hoping-like movement
else verticalSpeed = Mathf.Lerp(Velocity.Y, -AirGlideVSpeed, delta); var currentVelocity = Velocity.Length();
var horizontalVelocity = ComputeHVelocity(delta, AccelerationAirGlide, DecelerationAirGlide);
Velocity = new Vector3(horizontalVelocity.X, verticalSpeed, horizontalVelocity.Z); var verticalSpeed = Velocity.Y > 0 ? ComputeVerticalSpeedGravity(delta) : Mathf.Lerp(Velocity.Y, -AirGlideVSpeed, delta*AirGlideVerticalAcceleration);
var newVelocity = new Vector3(horizontalVelocity.X, verticalSpeed, horizontalVelocity.Z);
Velocity = newVelocity.Normalized() * currentVelocity;
}
else
{
// Preserve horizontal velocity only
// Allows for mor stable descent when gliding because you don't zoom away after a long fall
// Removes bunny-hoping-like movement by simply holding slide and jump jump jump
var currentHVelocity = new Vector2(Velocity.X, Velocity.Z).Length();
var horizontalVelocity = ComputeHVelocity(delta, AccelerationAirGlide, DecelerationAirGlide);
var newHVelocity = horizontalVelocity.Normalized() * currentHVelocity;
var verticalSpeed = Velocity.Y > 0 ? ComputeVerticalSpeedGravity(delta) : Mathf.Lerp(Velocity.Y, -AirGlideVSpeed, delta*AirGlideVerticalAcceleration);
var newVelocity = new Vector3(newHVelocity.X, verticalSpeed, newHVelocity.Z);
Velocity = newVelocity;
}
} }
public void HandleAirGlide(float delta) public void HandleAirGlide(float delta)
{ {
@@ -1260,6 +1306,16 @@ public partial class PlayerController : CharacterBody3D
{ {
_targetSpeed = WalkSpeed; _targetSpeed = WalkSpeed;
} }
public void JumpFromGroundSlide()
{
_jumpStrengthMultiplier = GroundSlideJumpMultiplier + Velocity.Length()*GroundSlideJumpSpeedFactor;
}
public void JumpFromAirGlide()
{
_jumpStrengthMultiplier = AirGlideJumpMultiplier + Velocity.Length()*AirGlideJumpSpeedFactor;
}
/////////////////////////// ///////////////////////////
// Slam Management /////// // Slam Management ///////