Movement turning smoothing

This commit is contained in:
Marco 2025-08-18 12:28:05 +02:00
commit f148e7cac7
2 changed files with 18 additions and 13 deletions

View file

@ -288,7 +288,6 @@ Acceleration = 150.0
Deceleration = 20.0 Deceleration = 20.0
Gravity = -20.0 Gravity = -20.0
FallSpeed = 4.0 FallSpeed = 4.0
TurnResistance = 0.8000000000029104
[node name="Storage" type="Node" parent="." node_paths=PackedStringArray("Root", "Shield")] [node name="Storage" type="Node" parent="." node_paths=PackedStringArray("Root", "Shield")]
script = ExtResource("6_habpy") script = ExtResource("6_habpy")

View file

@ -20,7 +20,8 @@ public partial class IsoMovementModule : ModuleBase<PlayerState, CharacterBody3D
[Export] public float Gravity = -9.8f; [Export] public float Gravity = -9.8f;
[Export] public float FallSpeed = 20f; [Export] public float FallSpeed = 20f;
[Export] public float TurnResistance { get; set; } = 0.5f; [Export] public float TurnResistance { get; set; } = 0.8f;
[Export] public float AxisReleaseFriction { get; set; } = 0.5f;
private bool _isStrafing; private bool _isStrafing;
private float _accelerationPerSecond; private float _accelerationPerSecond;
@ -77,40 +78,45 @@ public partial class IsoMovementModule : ModuleBase<PlayerState, CharacterBody3D
} }
private Vector2 InterpolateVelocityAxes( private Vector2 InterpolateVelocityAxes(
Vector2 current, Vector2 target, float accel, float decel, float delta) Vector2 current, Vector2 target, float accel, float decel, float turnResist, float releaseFriction, float delta)
{ {
float newX = current.X; float newX = current.X;
float newY = current.Y; float newY = current.Y;
// --- X Axis --- // --- X Axis ---
if (Mathf.Sign(target.X) == Mathf.Sign(current.X) || Mathf.IsZeroApprox(current.X)) if (Mathf.IsZeroApprox(target.X) && !Mathf.IsZeroApprox(current.X))
{
// No input on X → bleed velocity gradually instead of snapping to zero
newX = Mathf.MoveToward(current.X, 0, decel * releaseFriction * delta);
}
else 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; float step = (Mathf.Abs(target.X) > Mathf.Abs(current.X)) ? accel : decel;
newX = Mathf.MoveToward(current.X, target.X, step * delta); newX = Mathf.MoveToward(current.X, target.X, step * delta);
} }
else else
{ {
// Opposite direction → apply resistance multiplier to deceleration // Opposite direction → resistance
float slowStep = decel * TurnResistance; float slowStep = decel * turnResist;
newX = Mathf.MoveToward(current.X, 0, slowStep * delta); newX = Mathf.MoveToward(current.X, 0, slowStep * delta);
// Only start accelerating toward target if we've nearly stopped
if (Mathf.IsZeroApprox(newX)) if (Mathf.IsZeroApprox(newX))
newX = Mathf.MoveToward(newX, target.X, accel * delta); newX = Mathf.MoveToward(newX, target.X, accel * delta);
} }
// --- Y Axis --- // --- Y Axis ---
if (Mathf.Sign(target.Y) == Mathf.Sign(current.Y) || Mathf.IsZeroApprox(current.Y)) if (Mathf.IsZeroApprox(target.Y) && !Mathf.IsZeroApprox(current.Y))
{
newY = Mathf.MoveToward(current.Y, 0, decel * releaseFriction * delta);
}
else 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; float step = (Mathf.Abs(target.Y) > Mathf.Abs(current.Y)) ? accel : decel;
newY = Mathf.MoveToward(current.Y, target.Y, step * delta); newY = Mathf.MoveToward(current.Y, target.Y, step * delta);
} }
else else
{ {
float slowStep = decel * TurnResistance; float slowStep = decel * turnResist;
newY = Mathf.MoveToward(current.Y, 0, slowStep * delta); newY = Mathf.MoveToward(current.Y, 0, slowStep * delta);
if (Mathf.IsZeroApprox(newY)) if (Mathf.IsZeroApprox(newY))
newY = Mathf.MoveToward(newY, target.Y, accel * delta); newY = Mathf.MoveToward(newY, target.Y, accel * delta);
} }
@ -135,7 +141,7 @@ public partial class IsoMovementModule : ModuleBase<PlayerState, CharacterBody3D
else else
{ {
Vector2 targetVel = inputDir * Speed; Vector2 targetVel = inputDir * Speed;
v = InterpolateVelocityAxes(v, targetVel, Acceleration, Deceleration, dt); v = InterpolateVelocityAxes(v, targetVel, Acceleration, Deceleration, TurnResistance, AxisReleaseFriction, dt);
} }
float vy = Mathf.Clamp(v3.Y + Gravity * dt, -FallSpeed, FallSpeed); float vy = Mathf.Clamp(v3.Y + Gravity * dt, -FallSpeed, FallSpeed);