Added ground-like movement (i.e. air control when close to ground) and wall jumping away from the wall is always possible even when facing it

This commit is contained in:
2026-01-12 11:52:35 +01:00
parent 66be7838bb
commit 04054cfeae
3 changed files with 45 additions and 15 deletions

View File

@@ -44,6 +44,7 @@ public partial class PlayerController : CharacterBody3D
public MeshInstance3D DashIndicatorMesh;
public CylinderMesh DashIndicatorMeshCylinder;
public RayCast3D WallRunSnapper;
public ShapeCast3D GroundDetector;
private bool _movementEnabled = true;
@@ -296,6 +297,7 @@ public partial class PlayerController : CharacterBody3D
StairsSystem = GetNode<StairsSystem>("StairsSystem");
WallHugSystem = GetNode<WallHugSystem>("WallHugSystem");
WallRunSnapper = GetNode<RayCast3D>("%WallRunSnapper");
GroundDetector = GetNode<ShapeCast3D>("GroundDetector");
RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D");
RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D");
_headCollisionDetectors = new RayCast3D[NUM_OF_HEAD_COLLISION_DETECTORS];
@@ -442,6 +444,15 @@ public partial class PlayerController : CharacterBody3D
_onLeaveWallFromRunCoyote.Taken += OnLeaveWallFromRun;
}
public void OnGroundDetected(Node3D _)
{
GD.Print("Ground-like");
}
public void OnGroundLost(Node3D _)
{
GD.Print("Ground-less");
}
public void SetAllowedInputsAll()
{
CurrentlyAllowedInputs = AllowedInputs.All;
@@ -540,7 +551,8 @@ public partial class PlayerController : CharacterBody3D
public void HandleAirborne(float delta)
{
MoveInAir(delta);
var isGroundLike = GroundDetector.GetCollisionResult().Count > 0;
MoveInAir(delta, isGroundLike);
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
@@ -627,6 +639,9 @@ public partial class PlayerController : CharacterBody3D
public void HandleWallHugging(float delta)
{
_canDash = true;
_canDashAirborne = true;
WallHug(delta);
if (isOnFloorCustom())
_playerState.SendEvent("grounded");
@@ -642,6 +657,9 @@ public partial class PlayerController : CharacterBody3D
public void HandleWallRunning(float delta)
{
_canDash = false;
_canDashAirborne = false;
// Find horizontal velocity projected on the current wall
var hvel = new Vector3(Velocity.X, 0, Velocity.Z);
var hvelProjected = hvel.Slide(_wallHugStartNormal);
@@ -703,7 +721,6 @@ public partial class PlayerController : CharacterBody3D
return;
}
if (_onWall.Active && !_isWallJumpAvailable && IsFacingWall()) return;
_playerState.SendEvent("jump");
}
@@ -766,7 +783,7 @@ public partial class PlayerController : CharacterBody3D
public void OnJumpFromWall()
{
if (!IsFacingWall())
if (!IsFacingWall() || (!_isWallJumpAvailable && IsFacingWall()))
{
ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
}
@@ -1330,9 +1347,9 @@ public partial class PlayerController : CharacterBody3D
Velocity = new Vector3(horizontalVelocity.X, Velocity.Y, horizontalVelocity.Z);
}
public void MoveInAir(double delta)
public void MoveInAir(double delta, bool isGroundLike = false)
{
var horizontalVelocity = ComputeHVelocityAir((float) delta);
var horizontalVelocity = isGroundLike ? ComputeHVelocityGround((float) delta) : ComputeHVelocityAir((float) delta);
var verticalVelocity = Velocity.Y - (CalculateGravityForce() * (float)delta);
Velocity = new Vector3(horizontalVelocity.X, verticalVelocity, horizontalVelocity.Z);
}
@@ -1471,7 +1488,6 @@ public partial class PlayerController : CharacterBody3D
CameraModifications((float) delta);
HandleStairs((float) delta);
MantleSystem.ProcessMantle(_grounded.Active);
if (WeaponSystem.InHandState.Active)
RotateWeaponWithPlayer();