basic slide and air glide mechanic
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 17s
Create tag and build when new code gets to main / Export (push) Successful in 10m40s

This commit is contained in:
2026-01-12 17:47:32 +01:00
parent c7991198ea
commit 0e3e258fd3
5 changed files with 141 additions and 31 deletions

View File

@@ -129,6 +129,22 @@ public partial class PlayerController : CharacterBody3D
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float TimeScaleAimInAir { get; set; } = 0.05f;
// Sliding and gliding
[ExportGroup("Slide")]
[ExportSubgroup("Ground slide")]
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float AccelerationGroundSlide = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float DecelerationGroundSlide = 0.1f;
[ExportSubgroup("Air glide")]
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
public float AirGlideVSpeed { get; set; } = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float AccelerationAirGlide = 1.0f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float DecelerationAirGlide = 0.1f;
// Wall hug
[ExportGroup("Wall hug")]
[Export(PropertyHint.Range, "0,50,0.1,or_greater")]
@@ -235,6 +251,9 @@ public partial class PlayerController : CharacterBody3D
private StateChartState _mantling;
private StateChartState _simpleDash;
private StateChartState _aimedDash;
private StateChartState _sliding;
private StateChartState _groundSliding;
private StateChartState _airGliding;
private StateChartState _onWall;
private StateChartState _onWallHugging;
private StateChartState _onWallHanging;
@@ -293,12 +312,17 @@ public partial class PlayerController : CharacterBody3D
_playerHeight = playerShape!.Height;
_playerRadius = playerShape.Radius;
// State managementb
// State management
_playerState = StateChart.Of(GetNode("StateChart"));
_aiming = StateChartState.Of(GetNode("StateChart/Root/Aim/On"));
_simpleDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/Dash"));
_aimedDash = StateChartState.Of(GetNode("StateChart/Root/Movement/Dashing/AimedDash"));
_sliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding"));
_groundSliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/GroundSlide"));
_airGliding = StateChartState.Of(GetNode("StateChart/Root/Movement/Sliding/AirGlide"));
// _actionHanging = StateChartState.Of(GetNode("StateChart/Root/Actions/Hanging"));
_powerExpired = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Expired"));
_powerRecharging = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/AtLeastOneCharge"));
@@ -385,6 +409,11 @@ public partial class PlayerController : CharacterBody3D
_aimedDash.StateEntered += OnAimedDashStarted;
_aimedDash.StateExited += OnAimedDashFinished;
_sliding.StateEntered += SlideStarted;
_sliding.StateExited += SlideEnded;
_groundSliding.StatePhysicsProcessing += HandleGroundSlide;
_airGliding.StatePhysicsProcessing += HandleAirGlide;
_simpleDashCooldownTimer.Timeout += DashCooldownTimeout;
_airborneDashCooldownTimer.Timeout += AirborneDashCooldownTimeout;
@@ -480,6 +509,11 @@ public partial class PlayerController : CharacterBody3D
_bufferedAction = BufferedActions.None;
}
public bool IsGroundLike()
{
return GroundDetector.GetCollisionResult().Count > 0;
}
public void HandleGrounded(float delta)
{
@@ -572,8 +606,7 @@ public partial class PlayerController : CharacterBody3D
///////////////////////////
public void HandleAirborne(float delta)
{
var isGroundLike = GroundDetector.GetCollisionResult().Count > 0;
MoveInAir(delta, isGroundLike);
MoveInAir(delta, IsGroundLike());
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
@@ -610,10 +643,15 @@ public partial class PlayerController : CharacterBody3D
_playerState.SendEvent("wall_hug");
}
}
public float ComputeVerticalSpeedGravity(float delta)
{
return Velocity.Y - CalculateGravityForce() * delta;
}
public void MoveInAir(double delta, bool isGroundLike = false)
{
var horizontalVelocity = isGroundLike ? ComputeHVelocityGround((float) delta) : ComputeHVelocityAir((float) delta);
var verticalVelocity = Velocity.Y - (CalculateGravityForce() * (float)delta);
var verticalVelocity = ComputeVerticalSpeedGravity((float) delta);
Velocity = new Vector3(horizontalVelocity.X, verticalVelocity, horizontalVelocity.Z);
}
@@ -1102,18 +1140,65 @@ public partial class PlayerController : CharacterBody3D
_playerState.SendEvent("grounded");
}
///////////////////////////
// Slide management //
///////////////////////////
public void OnInputSlideStarted()
{
}
public void OnInputSlideOngoing()
{
_playerState.SendEvent("slide");
}
public void OnInputSlideEnded()
{
_playerState.SendEvent("slide_released");
}
public void SlideStarted()
{
_targetSpeed = Velocity.Length();
}
public void SlideOnGround(float delta)
{
var horizontalVelocity = ComputeHVelocity(delta, AccelerationGroundSlide, DecelerationGroundSlide);
Velocity = new Vector3(horizontalVelocity.X, Velocity.Y, horizontalVelocity.Z);
}
public void HandleGroundSlide(float delta)
{
SlideOnGround(delta);
if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward()) _playerState.SendEvent("mantle");
if (!isOnFloorCustom())
_playerState.SendEvent("start_falling");
}
public void GlideInAir(float delta)
{
var horizontalVelocity = ComputeHVelocity(delta, AccelerationAirGlide, DecelerationAirGlide);
float verticalSpeed;
if (Velocity.Y < -AirGlideVSpeed) verticalSpeed = -AirGlideVSpeed;
else if (Velocity.Y > 0) verticalSpeed = ComputeVerticalSpeedGravity(delta);
else verticalSpeed = Mathf.Lerp(Velocity.Y, -AirGlideVSpeed, delta);
Velocity = new Vector3(horizontalVelocity.X, verticalSpeed, horizontalVelocity.Z);
}
public void HandleAirGlide(float delta)
{
GlideInAir(delta);
if (MantleSystem.IsMantlePossible && IsPlayerInputtingForward()) _playerState.SendEvent("mantle");
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
}
public void SlideEnded()
{
_targetSpeed = WalkSpeed;
}
///////////////////////////
// Slam Management ///////
///////////////////////////
public void OnInputSlamPressed()
{
GD.Print("Slam pressed");
}
///////////////////////////
@@ -1221,14 +1306,6 @@ public partial class PlayerController : CharacterBody3D
}
}
///////////////////////////
// Slam Management ///////
///////////////////////////
public void OnInputSlamPressed()
{
GD.Print("Slam pressed");
}
///////////////////////////
// Parry Management ///////
///////////////////////////
@@ -1279,7 +1356,6 @@ public partial class PlayerController : CharacterBody3D
}
// Weapon dashing
public void ThrowWeapon()
{
_playerState.SendEvent("cancel_aim");