fine tuned wall jump and run again

This commit is contained in:
2026-02-13 12:31:51 +01:00
parent 22c4301244
commit 1caf202310
2 changed files with 55 additions and 15 deletions

View File

@@ -160,7 +160,7 @@ WallHugHorizontalDeceleration = 1.0
WallRunUpwardVelocityFactor = 0.5 WallRunUpwardVelocityFactor = 0.5
MinimumWallRunUpwardSpeed = 4.0 MinimumWallRunUpwardSpeed = 4.0
WallRunAltitudeLossSpeed = 8.0 WallRunAltitudeLossSpeed = 8.0
WallRunSpeedThreshold = 2.0 WallRunSpeedThreshold = 1.0
[node name="CHealth" parent="." unique_id=1244478698 instance=ExtResource("3_q7bng")] [node name="CHealth" parent="." unique_id=1244478698 instance=ExtResource("3_q7bng")]
RHealth = ExtResource("4_m8gvy") RHealth = ExtResource("4_m8gvy")
@@ -1120,7 +1120,7 @@ delay_in_seconds = "0.0"
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=342055859] [node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=342055859]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../Jump/SimpleJump") to = NodePath("../../Jump/SimpleJump")
event = &"jump" event = &"wall_jump"
delay_in_seconds = "0.0" delay_in_seconds = "0.0"
[node name="OnDash" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=43147957] [node name="OnDash" type="Node" parent="StateChart/Root/Movement/OnWall" unique_id=43147957]

View File

@@ -245,7 +245,7 @@ public partial class PlayerController : CharacterBody3D,
public float MinimumWallRunHorizontalSpeed { get; set; } = 12f; public float MinimumWallRunHorizontalSpeed { get; set; } = 12f;
[Export(PropertyHint.Range, "1,20,0.1,or_greater")] [Export(PropertyHint.Range, "1,20,0.1,or_greater")]
public float WallRunAltitudeLossSpeed { get; set; } = 10f; public float WallRunAltitudeLossSpeed { get; set; } = 10f;
[Export(PropertyHint.Range, "1,20,0.1,or_greater")] [Export(PropertyHint.Range, "0,20,0.1,or_greater")]
public float WallRunSpeedThreshold { get; set; } = 8f; public float WallRunSpeedThreshold { get; set; } = 8f;
/////////////////////////// ///////////////////////////
@@ -1192,11 +1192,15 @@ public partial class PlayerController : CharacterBody3D,
// return; // return;
var newWallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up); var newWallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up);
if (newWallNormal.AngleTo(_wallHugStartNormal) > Mathf.Pi/4) return; // if (newWallNormal.AngleTo(_wallHugStartNormal) > Mathf.Pi/4) return;
_wallHugStartNormal = newWallNormal; _wallHugStartNormal = newWallNormal;
} }
private float _timeOnWall;
public void OnWallStarted() public void OnWallStarted()
{ {
_timeOnWall = 0f;
if (_simpleDashCooldownTimer.IsStopped()) if (_simpleDashCooldownTimer.IsStopped())
_canDash = true; _canDash = true;
else else
@@ -1212,6 +1216,7 @@ public partial class PlayerController : CharacterBody3D,
} }
public void OnWallStopped() public void OnWallStopped()
{ {
_timeOnWall = 0f;
} }
public void OnLeaveWallFromRun() public void OnLeaveWallFromRun()
{ {
@@ -1221,8 +1226,12 @@ public partial class PlayerController : CharacterBody3D,
{ {
// _canDash = true; // _canDash = true;
// _canDashAirborne = true; // _canDashAirborne = true;
_timeOnWall += delta;
if (IsInputTowardsWall(_wallHugStartNormal))
WallHug(delta); WallHug(delta);
else
MoveInAir(delta, IsGroundLike());
// if (ShouldStartWallRun()) // if (ShouldStartWallRun())
// { // {
// _playerState.SendEvent("wall_run"); // _playerState.SendEvent("wall_run");
@@ -1230,7 +1239,7 @@ public partial class PlayerController : CharacterBody3D,
// } // }
if (isOnFloorCustom()) if (isOnFloorCustom())
_playerState.SendEvent("grounded"); _playerState.SendEvent("grounded");
if (!WallHugSystem.IsWallHugging() || !IsInputTowardsWall(_wallHugStartNormal)) if (!WallHugSystem.IsWallHugging())
_playerState.SendEvent("start_falling"); _playerState.SendEvent("start_falling");
} }
public void HandleWallHanging(float delta) public void HandleWallHanging(float delta)
@@ -1252,6 +1261,7 @@ public partial class PlayerController : CharacterBody3D,
{ {
// _canDash = false; // _canDash = false;
// _canDashAirborne = false; // _canDashAirborne = false;
_timeOnWall += delta;
// Find horizontal velocity projected on the current wall // Find horizontal velocity projected on the current wall
var hvel = new Vector3(Velocity.X, 0, Velocity.Z); var hvel = new Vector3(Velocity.X, 0, Velocity.Z);
@@ -1286,6 +1296,7 @@ public partial class PlayerController : CharacterBody3D,
public bool ShouldStartWallRun() public bool ShouldStartWallRun()
{ {
GD.Print(_wallHugStartNormal);
if (_wallHugStartNormal.Length() < Mathf.Epsilon) if (_wallHugStartNormal.Length() < Mathf.Epsilon)
{ {
// GD.Print("No wall normal"); // GD.Print("No wall normal");
@@ -1302,7 +1313,13 @@ public partial class PlayerController : CharacterBody3D,
var isThereInput = GetMoveInput().Length() > Mathf.Epsilon; var isThereInput = GetMoveInput().Length() > Mathf.Epsilon;
if (!isThereInput) if (!isThereInput)
{ {
// GD.Print("Not a wall"); // GD.Print("No input");
return false;
}
if (!IsInputForwardOrTowardsWall())
{
// GD.Print("Input isn't forward or towards wall");
return false; return false;
} }
@@ -1322,14 +1339,14 @@ public partial class PlayerController : CharacterBody3D,
return false; return false;
} }
var isCoplanarEnough = Math.Abs(Velocity.Normalized().Dot(_wallHugStartNormal)) < 0.5; var isCoplanarEnough = Math.Abs(Velocity.Normalized().Dot(_wallHugStartNormal)) < 0.9;
if (!isCoplanarEnough) if (!isCoplanarEnough)
{ {
// GD.Print("Not coplanar enough"); // GD.Print("Not coplanar enough");
return false; return false;
} }
var isGoingDownwards = Velocity.Normalized().Dot(Vector3.Down) > 0.5; var isGoingDownwards = Velocity.Normalized().Dot(Vector3.Down) > 0.7;
if (isGoingDownwards) if (isGoingDownwards)
{ {
// GD.Print("Going down"); // GD.Print("Going down");
@@ -1346,13 +1363,17 @@ public partial class PlayerController : CharacterBody3D,
return true; return true;
} }
public bool IsInputForwardOrTowardsWall()
{
return GetInputLocalHDirection().Z < -0.2f || IsInputTowardsWall(_wallHugStartNormal);
}
public bool CanKeepWallRun() public bool CanKeepWallRun()
{ {
var isThereInput = GetMoveInput().Length() > Mathf.Epsilon; var isThereInput = GetMoveInput().Length() > Mathf.Epsilon;
if (!isThereInput) return false; if (!isThereInput) return false;
var isInputForward = GetInputLocalHDirection().Z < 0; if (!IsInputForwardOrTowardsWall()) return false;
if (!isInputForward) return false;
var haveEnoughSpeed = Velocity.Length() > WallRunSpeedThreshold; var haveEnoughSpeed = Velocity.Length() > WallRunSpeedThreshold;
if (!haveEnoughSpeed) return false; if (!haveEnoughSpeed) return false;
@@ -1370,6 +1391,7 @@ public partial class PlayerController : CharacterBody3D,
} }
public void WallHang(float delta) public void WallHang(float delta)
{ {
_timeOnWall += 1; // Consider we've already spent quite some time on wall
Velocity = Vector3.Zero; Velocity = Vector3.Zero;
GlobalPosition = _wallHugStartLocation; GlobalPosition = _wallHugStartLocation;
} }
@@ -1417,10 +1439,19 @@ public partial class PlayerController : CharacterBody3D,
return; return;
} }
if (WallHugSystem.IsWallHugging())
if (_onWallRunning.Active || _onWallHanging.Active) // Always allow jumping out of wall run and hang
{ {
_playerState.SendEvent("wall_jump"); _playerState.SendEvent("wall_jump");
return;
} }
if (_onWallHugging.Active && _isWallJumpAvailable) // Limit number of jumps doable when hugging
{
_playerState.SendEvent("wall_jump");
return;
}
// Regular jump
_playerState.SendEvent("jump"); _playerState.SendEvent("jump");
} }
@@ -1516,13 +1547,22 @@ public partial class PlayerController : CharacterBody3D,
SetHorizontalVelocity(currentHorizontalVelocity + wallJumpHorizontalVelocity); SetHorizontalVelocity(currentHorizontalVelocity + wallJumpHorizontalVelocity);
} }
public void OnJumpFromWall()
public bool IsOnWallForLongEnough()
{ {
if (!IsFacingWall() || (!_isWallJumpAvailable && IsFacingWall())) return _timeOnWall >= 0.1f;
{
ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
} }
public void OnJumpFromWall()
{
// if (!IsFacingWall() || (!_isWallJumpAvailable && IsFacingWall()))
// {
// ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
// }
if (IsOnWallForLongEnough() || _onWallRunning.Active)
ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
// OnJumpStarted(DoubleJumpStartVelocity);
// Remove the ability to dash straight away so you cannot scale up the wall // Remove the ability to dash straight away so you cannot scale up the wall
// _canDashAirborne = false; // _canDashAirborne = false;
_airborneDashCooldownTimer.Start(); _airborneDashCooldownTimer.Start();