diff --git a/Scenes/Actors/IsoPlayer_FSM.tscn b/Scenes/Actors/IsoPlayer_FSM.tscn index 882a55ff..44fda0c6 100644 --- a/Scenes/Actors/IsoPlayer_FSM.tscn +++ b/Scenes/Actors/IsoPlayer_FSM.tscn @@ -288,7 +288,7 @@ Acceleration = 150.0 Deceleration = 20.0 Gravity = -20.0 FallSpeed = 4.0 -TurnSpeed = 1.0 +TurnResistance = 0.8000000000029104 [node name="Storage" type="Node" parent="." node_paths=PackedStringArray("Root", "Shield")] script = ExtResource("6_habpy") diff --git a/Scripts/Components/FSM/3DPlayer/IsoMovementModule.cs b/Scripts/Components/FSM/3DPlayer/IsoMovementModule.cs index 0a66e140..16682a16 100644 --- a/Scripts/Components/FSM/3DPlayer/IsoMovementModule.cs +++ b/Scripts/Components/FSM/3DPlayer/IsoMovementModule.cs @@ -8,18 +8,20 @@ namespace Cirno.Scripts.Components.FSM._3DPlayer; public partial class IsoMovementModule : ModuleBase { - [Export] public IsoPlayerStorageModule PlayerStorage { get; private set; } + [Export] public IsoPlayerStorageModule PlayerStorage { get; private set; } [Export] private InputProvider _inputProvider; - + [Export] public PlayerHitboxSpriteProvider3D HitboxSpriteProvider { get; private set; } - + [Export] public int Speed { get; set; } = 45; [Export] public int StrafeSpeed { get; set; } = 35; [Export] public float Acceleration = 8f; [Export] public float Deceleration = 8f; [Export] public float Gravity = -9.8f; [Export] public float FallSpeed = 20f; - + + [Export] public float TurnResistance { get; set; } = 0.5f; + private bool _isStrafing; private float _accelerationPerSecond; private float _decelerationPerSecond; @@ -28,7 +30,7 @@ public partial class IsoMovementModule : ModuleBase _stateMachine; private CharacterBody3D MainObject => _stateMachine.MainObject; - + public override void EnterState(PlayerState state) { _accelerationPerSecond = Speed / Acceleration; @@ -37,7 +39,6 @@ public partial class IsoMovementModule : ModuleBase machine) @@ -48,10 +49,10 @@ public partial class IsoMovementModule : ModuleBase Mathf.Abs(current.X)) ? accel : decel; - float stepY = (Mathf.Abs(target.Y) > Mathf.Abs(current.Y)) ? accel : decel; + float newX = current.X; + float newY = current.Y; + + // --- X Axis --- + if (Mathf.Sign(target.X) == Mathf.Sign(current.X) || Mathf.IsZeroApprox(current.X)) + { + // Same direction or stopped → normal accel/decel + float step = (Mathf.Abs(target.X) > Mathf.Abs(current.X)) ? accel : decel; + newX = Mathf.MoveToward(current.X, target.X, step * delta); + } + else + { + // Opposite direction → apply resistance multiplier to deceleration + float slowStep = decel * TurnResistance; + newX = Mathf.MoveToward(current.X, 0, slowStep * delta); + + // Only start accelerating toward target if we've nearly stopped + if (Mathf.IsZeroApprox(newX)) + newX = Mathf.MoveToward(newX, target.X, accel * delta); + } + + // --- Y Axis --- + if (Mathf.Sign(target.Y) == Mathf.Sign(current.Y) || Mathf.IsZeroApprox(current.Y)) + { + float step = (Mathf.Abs(target.Y) > Mathf.Abs(current.Y)) ? accel : decel; + newY = Mathf.MoveToward(current.Y, target.Y, step * delta); + } + else + { + float slowStep = decel * TurnResistance; + newY = Mathf.MoveToward(current.Y, 0, slowStep * delta); + + if (Mathf.IsZeroApprox(newY)) + newY = Mathf.MoveToward(newY, target.Y, accel * delta); + } - float newX = Mathf.MoveToward(current.X, target.X, stepX * delta); - float newY = Mathf.MoveToward(current.Y, target.Y, stepY * delta); return new Vector2(newX, newY); } @@ -93,29 +124,20 @@ public partial class IsoMovementModule : ModuleBase 1f) - inputDir /= len; + if (inputDir.Length() > 1f) + inputDir = inputDir.Normalized(); if (_isStrafing) { - // Strafing stays instant/responsive if you want that behavior v = inputDir * StrafeSpeed; } else { - // Build a target *velocity* (not just direction) Vector2 targetVel = inputDir * Speed; - - // Per-axis interpolation prevents direction snaps when keys change v = InterpolateVelocityAxes(v, targetVel, Acceleration, Deceleration, dt); } - // Y (gravity) float vy = Mathf.Clamp(v3.Y + Gravity * dt, -FallSpeed, FallSpeed); if (Input.IsKeyLabelPressed(Key.Z)) vy = 10;