diff --git a/player_controller/PlayerController.tscn b/player_controller/PlayerController.tscn index 9a3074c7..1fec3bf1 100644 --- a/player_controller/PlayerController.tscn +++ b/player_controller/PlayerController.tscn @@ -69,6 +69,7 @@ Weight = 4.0 MantleTime = 0.3 MantlePath = ExtResource("2_6lejt") CoyoteTime = 0.3 +InputBufferFrames = 5 SimpleJumpStartVelocity = 6.0 SimpleJumpHangTimeInFrames = 1 SimpleJumpGravityLesseningFactor = 2.0 diff --git a/player_controller/Scripts/PlayerController.cs b/player_controller/Scripts/PlayerController.cs index a2f85463..f0e01c88 100644 --- a/player_controller/Scripts/PlayerController.cs +++ b/player_controller/Scripts/PlayerController.cs @@ -89,6 +89,8 @@ public partial class PlayerController : CharacterBody3D [ExportGroup("Jump")] [Export(PropertyHint.Range, "0,1,0.01")] public float CoyoteTime { get; set; } = 0.2f; + [Export(PropertyHint.Range, "0,10,1,or_greater")] + public int InputBufferFrames { get; set; } = 3; // Simple jump [ExportSubgroup("Simple jump")] @@ -229,6 +231,8 @@ public partial class PlayerController : CharacterBody3D private Transition _onLeaveWallFromRunCoyote; private Transition _onLeaveWallFromRun; + private int _currentJumpBufferFrames = 0; + private float _playerHeight; private float _playerRadius; private bool _isJumpInputPressed; @@ -466,6 +470,12 @@ public partial class PlayerController : CharacterBody3D if (_simpleDashCooldownTimer.IsStopped()) _simpleDashCooldownTimer.Start(); + + if (_currentJumpBufferFrames > 0) + { + _currentJumpBufferFrames = 0; + PerformJump(); + } } public void DashCooldownTimeout() @@ -639,7 +649,13 @@ public partial class PlayerController : CharacterBody3D // Jump public void OnInputJumpStarted() { + _currentJumpBufferFrames = InputBufferFrames; _isJumpInputPressed = true; + PerformJump(); + } + + public void PerformJump() + { if (MantleSystem.IsMantlePossible) { _playerState.SendEvent("mantle"); @@ -870,8 +886,8 @@ public partial class PlayerController : CharacterBody3D SetVerticalVelocity(Velocity.Y - 2.0f); } - // Move back to Airborne state management when starting to go down again - if (_framesSinceJumpAtApex > hangFrames) + // Move back to Airborne state when starting to go down again or if input isn't held anymore (buffered jump) + if (_framesSinceJumpAtApex > hangFrames || !_isJumpInputPressed) _playerState.SendEvent("jump_ended"); } public void HandleSimpleJump(float delta) @@ -1395,6 +1411,8 @@ public partial class PlayerController : CharacterBody3D /////////////////////////// public override void _PhysicsProcess(double delta) { + if (_currentJumpBufferFrames > 0) _currentJumpBufferFrames -= 1; + LookAround(delta); CameraModifications((float) delta); HandleStairs((float) delta);