small improvements on the wall run
All checks were successful
Create tag and build when new code gets to main / BumpTag (push) Successful in 18s
Create tag and build when new code gets to main / Export (push) Successful in 5m54s

This commit is contained in:
2025-11-14 16:39:17 +01:00
parent 0b0163a0ac
commit fabafbb35b
3 changed files with 53 additions and 25 deletions

View File

@@ -30,6 +30,7 @@ glow_enabled = true
[node name="Player" parent="." instance=ExtResource("1_1s2y7")] [node name="Player" parent="." instance=ExtResource("1_1s2y7")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1.5) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1.5)
TutorialDone = true
[node name="WorldEnvironment" type="WorldEnvironment" parent="."] [node name="WorldEnvironment" type="WorldEnvironment" parent="."]
environment = SubResource("Environment_1bvp3") environment = SubResource("Environment_1bvp3")

View File

@@ -84,6 +84,14 @@ PostDashSpeed = 30.0
WallHugGravityLesseningFactor = 15.0 WallHugGravityLesseningFactor = 15.0
WallHugDownwardMaxSpeed = 8.0 WallHugDownwardMaxSpeed = 8.0
WallHugHorizontalDeceleration = 0.5 WallHugHorizontalDeceleration = 0.5
WallRunAltitudeLossSpeed = 12.0
WallRunSpeedThreshold = 5.0
[node name="WallRunSnapper" type="RayCast3D" parent="."]
unique_name_in_owner = true
transform = Transform3D(0.99999994, 0, 0, 0, 1, 0, 0, 0, 0.99999994, 0, 0, 0)
target_position = Vector3(0, 0, -5)
collision_mask = 2
[node name="InputController" type="Node3D" parent="."] [node name="InputController" type="Node3D" parent="."]
script = ExtResource("16_v31n3") script = ExtResource("16_v31n3")
@@ -163,7 +171,6 @@ target_position = Vector3(0, 1, 0)
[node name="TweenQueueSystem" parent="." instance=ExtResource("22_rpwev")] [node name="TweenQueueSystem" parent="." instance=ExtResource("22_rpwev")]
[node name="WallHugSystem" type="Node3D" parent="."] [node name="WallHugSystem" type="Node3D" parent="."]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
script = ExtResource("27_n7qhm") script = ExtResource("27_n7qhm")
[node name="back" type="RayCast3D" parent="WallHugSystem"] [node name="back" type="RayCast3D" parent="WallHugSystem"]

View File

@@ -35,6 +35,7 @@ public partial class PlayerController : CharacterBody3D
public Node3D DashIndicatorNode; public Node3D DashIndicatorNode;
public MeshInstance3D DashIndicatorMesh; public MeshInstance3D DashIndicatorMesh;
public CylinderMesh DashIndicatorMeshCylinder; public CylinderMesh DashIndicatorMeshCylinder;
public RayCast3D WallRunSnapper;
private bool _movementEnabled = true; private bool _movementEnabled = true;
@@ -154,6 +155,16 @@ public partial class PlayerController : CharacterBody3D
[Export(PropertyHint.Range, "0.1,10,0.1,or_greater")] [Export(PropertyHint.Range, "0.1,10,0.1,or_greater")]
public float WallHugHorizontalDeceleration { get; set; } = 5f; public float WallHugHorizontalDeceleration { get; set; } = 5f;
// Wall run
[ExportGroup("Wall run")]
[Export(PropertyHint.Range, "1,20,0.1,or_greater")]
public float WallRunUpwardVelocity { get; set; } = 10f;
[Export(PropertyHint.Range, "1,20,0.1,or_greater")]
public float WallRunAltitudeLossSpeed { get; set; } = 10f;
[Export(PropertyHint.Range, "1,20,0.1,or_greater")]
public float WallRunSpeedThreshold { get; set; } = 8f;
private float _targetSpeed; private float _targetSpeed;
private float _gravity; private float _gravity;
@@ -246,6 +257,7 @@ public partial class PlayerController : CharacterBody3D
DashSystem = GetNode<DashSystem>("DashSystem"); DashSystem = GetNode<DashSystem>("DashSystem");
StairsSystem = GetNode<StairsSystem>("StairsSystem"); StairsSystem = GetNode<StairsSystem>("StairsSystem");
WallHugSystem = GetNode<WallHugSystem>("WallHugSystem"); WallHugSystem = GetNode<WallHugSystem>("WallHugSystem");
WallRunSnapper = GetNode<RayCast3D>("%WallRunSnapper");
RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D"); RayCast3D stairsBelowRayCast3D = GetNode<RayCast3D>("StairsBelowRayCast3D");
RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D"); RayCast3D stairsAheadRayCast3D = GetNode<RayCast3D>("StairsAheadRayCast3D");
_headCollisionDetectors = new RayCast3D[NUM_OF_HEAD_COLLISION_DETECTORS]; _headCollisionDetectors = new RayCast3D[NUM_OF_HEAD_COLLISION_DETECTORS];
@@ -427,8 +439,6 @@ public partial class PlayerController : CharacterBody3D
_playerState.SendEvent("start_falling"); _playerState.SendEvent("start_falling");
} }
private float _wallRunSpeedThreshold = 8f;
public void HandleAirborne(float delta) public void HandleAirborne(float delta)
{ {
MoveInAir(delta); MoveInAir(delta);
@@ -444,19 +454,21 @@ public partial class PlayerController : CharacterBody3D
// Should we start a wall run // Should we start a wall run
var wallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Zero); var wallNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Zero);
var isIndeedWall = wallNormal.Y < 0.1;
var hvel = new Vector3(Velocity.X, 0, Velocity.Z); var hvel = new Vector3(Velocity.X, 0, Velocity.Z);
var hvelProjected = hvel.Slide(_wallHugStartNormal); var hvelProjected = hvel.Slide(_wallHugStartNormal);
var haveEnoughSpeed = hvelProjected.Length() > _wallRunSpeedThreshold; var haveEnoughSpeed = hvelProjected.Length() > WallRunSpeedThreshold;
var isHeadPlanting = Velocity.AngleTo(wallNormal) < Math.PI / 4; var isCoplanarEnough = Velocity.AngleTo(wallNormal) > Math.PI/4 && Velocity.AngleTo(wallNormal) < 3*Math.PI/4;
var isGoingDownwards = Velocity.AngleTo(Vector3.Down) < Math.PI / 4; var isGoingDownwards = Velocity.AngleTo(Vector3.Down) < Math.PI/4;
if (haveEnoughSpeed && !isHeadPlanting && !isGoingDownwards) if (haveEnoughSpeed && isCoplanarEnough && !isGoingDownwards && isIndeedWall && !_coyoteEnabled.Active)
{ {
SetVerticalVelocity(WallRunUpwardVelocity);
_playerState.SendEvent("wall_run"); _playerState.SendEvent("wall_run");
return; return;
} }
// If all else fail and we go down, we hug // If all else fail and we go down, we hug
if (Velocity.Y < 0) if (Velocity.Y < 0 && !_coyoteEnabled.Active)
_playerState.SendEvent("wall_hug"); _playerState.SendEvent("wall_hug");
} }
@@ -476,14 +488,11 @@ public partial class PlayerController : CharacterBody3D
_wallHugStartNormal = newWallNormal; _wallHugStartNormal = newWallNormal;
} }
private float _timeSinceWallStarted;
public void OnWallStarted() public void OnWallStarted()
{ {
_wallHugStartNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up); _wallHugStartNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up);
_wallHugStartLocation = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero) + _wallHugStartNormal * _playerRadius; _wallHugStartLocation = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero) + _wallHugStartNormal * _playerRadius;
_wallHugStartProjectedVelocity = Velocity.Slide(_wallHugStartNormal); _wallHugStartProjectedVelocity = Velocity.Slide(_wallHugStartNormal);
_timeSinceWallStarted = 0;
} }
public void OnWallStopped() public void OnWallStopped()
@@ -505,23 +514,26 @@ public partial class PlayerController : CharacterBody3D
WallHang(delta); WallHang(delta);
} }
private float _wallRunUpwardVelocity = 10f;
public void HandleWallRunning(float delta) public void HandleWallRunning(float delta)
{ {
_timeSinceWallStarted += delta; // 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);
var hvelProjected = hvel.Slide(_wallHugStartNormal); var hvelProjected = hvel.Slide(_wallHugStartNormal);
Velocity = hvelProjected + hvelProjected.Length()*Vector3.Up*0.3f/(1+_timeSinceWallStarted);
Velocity *= 0.99f;
// if (CanMantle()) // Reorient horizontal velocity so we keep it coplanar with the wall without losing speed
// { var finalHVel = hvelProjected.Normalized() * hvel.Length();
// MantleToLocation(_plannedMantleLocation.Unwrap());
// }
if (!WallHugSystem.IsWallHugging() || Velocity.Length() < _wallRunSpeedThreshold) // Adapt vertical speed
var verticalSpeed = Velocity.Y - WallRunAltitudeLossSpeed * delta;
Velocity = finalHVel + Vector3.Up*verticalSpeed;
Velocity *= 0.995f;
if (WallRunSnapper.IsColliding())
{
GD.Print((WallRunSnapper.GetCollisionPoint() - WallRunSnapper.GlobalPosition).Length());
}
if (!WallHugSystem.IsWallHugging() || Velocity.Length() < WallRunSpeedThreshold)
{ {
_playerState.SendEvent("start_falling"); _playerState.SendEvent("start_falling");
} }
@@ -549,7 +561,10 @@ public partial class PlayerController : CharacterBody3D
{ {
if (CanMantle()) if (CanMantle())
{ {
MantleToLocation(_plannedMantleLocation.Unwrap()); var location = _plannedMantleLocation.UnwrapOr(Vector3.Zero);
if (location == Vector3.Zero)
return; // For some reason CanMantle can return an invalid location so fuck off I guess
MantleToLocation(location);
return; return;
} }
@@ -558,6 +573,7 @@ public partial class PlayerController : CharacterBody3D
_playerState.SendEvent("megajump"); _playerState.SendEvent("megajump");
return; return;
} }
_playerState.SendEvent("jump"); _playerState.SendEvent("jump");
} }
@@ -582,6 +598,7 @@ public partial class PlayerController : CharacterBody3D
public void OnDoubleJumpStarted() public void OnDoubleJumpStarted()
{ {
_canDash = true; _canDash = true;
_canDashAirborne = true;
OnJumpStarted(DoubleJumpStartVelocity); OnJumpStarted(DoubleJumpStartVelocity);
} }
public void OnMegaJumpStarted() public void OnMegaJumpStarted()
@@ -943,6 +960,9 @@ public partial class PlayerController : CharacterBody3D
public void PlaceWeaponForTutorial() public void PlaceWeaponForTutorial()
{ {
if (TutorialDone)
return;
RemoveChild(WeaponRoot); RemoveChild(WeaponRoot);
GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, WeaponRoot); GetTree().GetRoot().CallDeferred(Node.MethodName.AddChild, WeaponRoot);
WeaponRoot.CallDeferred(Node3D.MethodName.SetGlobalPosition, TutorialWeaponTarget.GlobalPosition); WeaponRoot.CallDeferred(Node3D.MethodName.SetGlobalPosition, TutorialWeaponTarget.GlobalPosition);
@@ -1158,7 +1178,7 @@ public partial class PlayerController : CharacterBody3D
Bobbing.CameraBobbingParams cameraBobbingParams = new Bobbing.CameraBobbingParams Bobbing.CameraBobbingParams cameraBobbingParams = new Bobbing.CameraBobbingParams
{ {
Delta = delta, Delta = delta,
IsOnFloorCustom = isOnFloorCustom(), IsOnFloorCustom = isOnFloorCustom() || _onWallRunning.Active,
Velocity = Velocity, Velocity = Velocity,
SettingsMultiplier = _headBobbingMultiplier SettingsMultiplier = _headBobbingMultiplier
}; };