small improvements on the wall run
This commit is contained in:
@@ -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")
|
||||||
|
|||||||
@@ -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"]
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user