revamped the dash, fixed an infinite jump issue and fixed buffered inputs
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 20s
Create tag and build when new code gets to main / Export (push) Successful in 10m15s

This commit is contained in:
2026-01-13 11:18:56 +01:00
parent 80e533d98e
commit 2fa4ce68e7
2 changed files with 81 additions and 28 deletions

View File

@@ -84,13 +84,14 @@ DoubleJumpHangTimeInFrames = 3
DoubleJumpGravityLesseningFactor = 1.5 DoubleJumpGravityLesseningFactor = 1.5
WallJumpStartVelocity = 8.0 WallJumpStartVelocity = 8.0
MaxNumberOfEmpoweredActions = 3 MaxNumberOfEmpoweredActions = 3
SimpleDashStrength = 15.0 SimpleDashStrength = 18.0
SimpleDashTime = 0.2
AimedDashTime = 0.2 AimedDashTime = 0.2
PostDashSpeed = 30.0 PostDashSpeed = 30.0
SlamSpeed = 80.0
AccelerationGroundSlide = 0.2 AccelerationGroundSlide = 0.2
AirGlideVSpeed = 3.0 AirGlideVSpeed = 4.0
AccelerationAirGlide = 0.2 AccelerationAirGlide = 0.2
DecelerationAirGlide = 0.0
WallHugGravityLesseningFactor = 15.0 WallHugGravityLesseningFactor = 15.0
WallHugDownwardMaxSpeed = 4.0 WallHugDownwardMaxSpeed = 4.0
WallHugHorizontalDeceleration = 1.0 WallHugHorizontalDeceleration = 1.0
@@ -723,7 +724,7 @@ delay_in_seconds = "0.0"
[node name="OnWallJump" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"] [node name="OnWallJump" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../../Jump/DoubleJump") to = NodePath("../../../Jump/DoubleJump")
event = &"jump" event = &"wall_jump"
delay_in_seconds = "0.0" delay_in_seconds = "0.0"
[node name="OnWall" type="Node" parent="StateChart/Root/Movement"] [node name="OnWall" type="Node" parent="StateChart/Root/Movement"]

View File

@@ -118,8 +118,10 @@ public partial class PlayerController : CharacterBody3D
public int MaxNumberOfEmpoweredActions { get; set; } = 1; public int MaxNumberOfEmpoweredActions { get; set; } = 1;
// Simple dash // Simple dash
[ExportSubgroup("Simple")] [ExportSubgroup("Simple")]
[Export(PropertyHint.Range, "0,50,0.1")] [Export(PropertyHint.Range, "0,50,0.1,or_greater")]
public float SimpleDashStrength { get; set; } = 10f; public float SimpleDashStrength { get; set; } = 10f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float SimpleDashTime { get; set; } = 0.5f;
// Aimed Dash // Aimed Dash
[ExportSubgroup("Special")] [ExportSubgroup("Special")]
[Export(PropertyHint.Range, "0,1,0.01,or_greater")] [Export(PropertyHint.Range, "0,1,0.01,or_greater")]
@@ -491,6 +493,7 @@ public partial class PlayerController : CharacterBody3D
/////////////////////////// ///////////////////////////
// Grounded management // // Grounded management //
/////////////////////////// ///////////////////////////
public void OnGrounded() public void OnGrounded()
{ {
_isWallJumpAvailable = true; _isWallJumpAvailable = true;
@@ -499,28 +502,36 @@ public partial class PlayerController : CharacterBody3D
if (_simpleDashCooldownTimer.IsStopped()) if (_simpleDashCooldownTimer.IsStopped())
_simpleDashCooldownTimer.Start(); _simpleDashCooldownTimer.Start();
if (_bufferedAction == BufferedActions.Jump && _currentInputBufferFrames > 0)
{
_currentInputBufferFrames = 0;
PerformJump();
}
if (_bufferedAction == BufferedActions.Dash && _currentInputBufferFrames > 0)
{
_currentInputBufferFrames = 0;
SimpleDash();
}
if (_bufferedAction == BufferedActions.MantleJump) if (_bufferedAction == BufferedActions.MantleJump)
{ {
SimpleDash(); _playerState.SendEvent("jump");
OnJumpStarted(MantleJumpStartVelocity);
} }
if (_bufferedAction == BufferedActions.MantleDash) if (_bufferedAction == BufferedActions.MantleDash)
{ {
SimpleDash(MantleDashStrength); if (GetMoveInput().Length() < Mathf.Epsilon)
{
_bufferedAction = BufferedActions.None;
return;
}
_playerState.SendEvent("dash");
} }
_bufferedAction = BufferedActions.None; if (_bufferedAction == BufferedActions.Jump && _currentInputBufferFrames > 0)
{
_currentInputBufferFrames = 0;
_playerState.SendEvent("jump");
}
if (_bufferedAction == BufferedActions.Dash && _currentInputBufferFrames > 0)
{
if (GetMoveInput().Length() < Mathf.Epsilon)
{
_bufferedAction = BufferedActions.None;
return;
}
_currentInputBufferFrames = 0;
_playerState.SendEvent("dash");
}
} }
public bool IsGroundLike() public bool IsGroundLike()
@@ -853,6 +864,12 @@ public partial class PlayerController : CharacterBody3D
return; return;
} }
if (GetMoveInput().Length() < Mathf.Epsilon) return;
// Buffer dash in case of mantle or inputting dash airborne before touching the ground without air dash available
_currentInputBufferFrames = InputBufferFrames;
_bufferedAction = _mantling.Active ? BufferedActions.MantleDash : BufferedActions.Dash;
if (_airborne.Active) if (_airborne.Active)
{ {
if (!_canDashAirborne) if (!_canDashAirborne)
@@ -860,14 +877,14 @@ public partial class PlayerController : CharacterBody3D
_canDashAirborne = false; _canDashAirborne = false;
} }
_currentInputBufferFrames = InputBufferFrames;
_bufferedAction = _mantling.Active ? BufferedActions.MantleDash : BufferedActions.Dash;
_playerState.SendEvent("dash"); _playerState.SendEvent("dash");
} }
public void SimpleDashInDirection(Vector3 direction, float strength = -1) public void SimpleDashInDirection(Vector3 direction, float strength = -1)
{ {
if (strength < 0) strength = SimpleDashStrength; if (strength < 0) strength = SimpleDashStrength;
SetVelocity(direction * strength); SetVelocity(direction * strength);
GetTree().CreateTimer(SimpleDashTime).Timeout += SimpleDashFinished;
} }
public void SimpleDash(float strength = -1) public void SimpleDash(float strength = -1)
{ {
@@ -876,12 +893,32 @@ public partial class PlayerController : CharacterBody3D
public void OnSimpleDashStarted() public void OnSimpleDashStarted()
{ {
if (!_canDash) if (_bufferedAction == BufferedActions.MantleDash)
{
SimpleDash(MantleDashStrength);
_bufferedAction = BufferedActions.None;
return; return;
}
if (!_canDash)
{
_playerState.SendEvent("dash_finished");
return;
}
_canDash = false; _canDash = false;
SimpleDash(); SimpleDash();
_bufferedAction = BufferedActions.None;
} }
public void HandleSimpleDash(float delta) public void HandleSimpleDash(float delta)
{
if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward())
{
_bufferedAction = BufferedActions.MantleDash;
_playerState.SendEvent("mantle");
}
}
public void SimpleDashFinished()
{ {
_playerState.SendEvent("dash_finished"); _playerState.SendEvent("dash_finished");
} }
@@ -996,7 +1033,9 @@ public partial class PlayerController : CharacterBody3D
public void OnInputJumpStarted() public void OnInputJumpStarted()
{ {
_currentInputBufferFrames = InputBufferFrames; _currentInputBufferFrames = InputBufferFrames;
_bufferedAction = _mantling.Active ? BufferedActions.MantleJump : BufferedActions.Jump; if (_mantling.Active) _bufferedAction = BufferedActions.MantleJump;
// Don't overwrite mantle jump buffered action
else if (_bufferedAction == BufferedActions.None) _bufferedAction = BufferedActions.Jump;
_isJumpInputPressed = true; _isJumpInputPressed = true;
PerformJump(); PerformJump();
@@ -1012,12 +1051,16 @@ public partial class PlayerController : CharacterBody3D
public void PerformJump() public void PerformJump()
{ {
if (MantleSystem.IsMantlePossible) if (MantleSystem.IsMantlePossible && !_mantling.Active)
{ {
_playerState.SendEvent("mantle"); _playerState.SendEvent("mantle");
return; return;
} }
if (WallHugSystem.IsWallHugging())
{
_playerState.SendEvent("wall_jump");
}
_playerState.SendEvent("jump"); _playerState.SendEvent("jump");
} }
@@ -1028,13 +1071,22 @@ public partial class PlayerController : CharacterBody3D
} }
public void OnSimpleJumpStarted() public void OnSimpleJumpStarted()
{ {
if (_bufferedAction == BufferedActions.MantleJump)
{
SetVelocity(GetInputGlobalHDirection()*SimpleDashStrength);
OnJumpStarted(MantleJumpStartVelocity);
_bufferedAction = BufferedActions.None;
return;
}
OnJumpStarted(SimpleJumpStartVelocity); OnJumpStarted(SimpleJumpStartVelocity);
_bufferedAction = BufferedActions.None;
} }
public void OnDoubleJumpStarted() public void OnDoubleJumpStarted()
{ {
_canDash = true; _canDash = true;
// _canDashAirborne = true; // _canDashAirborne = true;
OnJumpStarted(DoubleJumpStartVelocity); OnJumpStarted(DoubleJumpStartVelocity);
_bufferedAction = BufferedActions.None;
} }
public void HandleJump(float delta, float gravityFactor, int hangFrames) public void HandleJump(float delta, float gravityFactor, int hangFrames)