new broken mantle system and fixed lots of gamefeel regarding wall hugs and jumps and coyote time
This commit is contained in:
@@ -133,6 +133,11 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
|
||||
CameraInclineAcceleration = 20.0
|
||||
GroundedCameraIncline = 3.0
|
||||
|
||||
[node name="MantleSystem" parent="HeadSystem" instance=ExtResource("8_qu4wy")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.6, 0)
|
||||
MantleEndLocationDistanceFromWall = 0.3
|
||||
MantleHeightCastStart = 2.5
|
||||
|
||||
[node name="StairsSystem" type="Node3D" parent="."]
|
||||
script = ExtResource("7_bmt5a")
|
||||
|
||||
@@ -143,10 +148,6 @@ target_position = Vector3(0, -0.55, 0)
|
||||
[node name="StairsBelowRayCast3D" type="RayCast3D" parent="."]
|
||||
target_position = Vector3(0, -0.75, 0)
|
||||
|
||||
[node name="MantleSystem" parent="." instance=ExtResource("8_qu4wy")]
|
||||
MantleEndLocationDistanceFromWall = 0.3
|
||||
MantleHeightCastStart = 2.0
|
||||
|
||||
[node name="Bobbing" type="Node3D" parent="."]
|
||||
script = ExtResource("10_7wk1w")
|
||||
|
||||
@@ -154,6 +155,7 @@ script = ExtResource("10_7wk1w")
|
||||
script = ExtResource("12_m2mxi")
|
||||
|
||||
[node name="HeadCollisionDetectors" type="Node3D" parent="."]
|
||||
visible = false
|
||||
|
||||
[node name="HeadCollisionDetector0" type="RayCast3D" parent="HeadCollisionDetectors"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.4, -0.210707)
|
||||
@@ -174,6 +176,7 @@ target_position = Vector3(0, 1, 0)
|
||||
[node name="TweenQueueSystem" parent="." instance=ExtResource("22_rpwev")]
|
||||
|
||||
[node name="WallHugSystem" type="Node3D" parent="."]
|
||||
visible = false
|
||||
script = ExtResource("27_n7qhm")
|
||||
|
||||
[node name="back" type="RayCast3D" parent="WallHugSystem"]
|
||||
@@ -243,7 +246,6 @@ one_shot = true
|
||||
ignore_time_scale = true
|
||||
|
||||
[node name="StateChartDebugger" parent="." instance=ExtResource("24_q5h8a")]
|
||||
visible = false
|
||||
offset_left = 1524.0
|
||||
offset_top = 1.0
|
||||
offset_right = -8.0
|
||||
@@ -602,12 +604,6 @@ initial_state = NodePath("CoyoteEnabled")
|
||||
script = ExtResource("41_ruloh")
|
||||
default_state = NodePath("../CoyoteEnabled")
|
||||
|
||||
[node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../OnWall/HuggingCoyoteEnabled")
|
||||
event = &"wall_hug"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="OnWallRun" type="Node" parent="StateChart/Root/Movement/Airborne"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../OnWall/RunningCoyoteEnabled")
|
||||
@@ -650,6 +646,12 @@ delay_in_seconds = "0.0"
|
||||
[node name="DoubleJumpEnabled" type="Node" parent="StateChart/Root/Movement/Airborne"]
|
||||
script = ExtResource("27_34snm")
|
||||
|
||||
[node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne/DoubleJumpEnabled"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../../OnWall/HuggingCoyoteEnabled")
|
||||
event = &"wall_hug"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="OnMegajump" type="Node" parent="StateChart/Root/Movement/Airborne/DoubleJumpEnabled"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../../Jump/MegaJump")
|
||||
@@ -665,6 +667,12 @@ delay_in_seconds = "0.0"
|
||||
[node name="Falling" type="Node" parent="StateChart/Root/Movement/Airborne"]
|
||||
script = ExtResource("27_34snm")
|
||||
|
||||
[node name="OnWallHug" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../../OnWall/HuggingCoyoteEnabled")
|
||||
event = &"wall_hug"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="ToDoubleJump" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../DoubleJumpEnabled")
|
||||
@@ -708,6 +716,12 @@ to = NodePath("../../Hugging")
|
||||
event = &"coyote_expired"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/HuggingCoyoteEnabled"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../../Jump/DoubleJump")
|
||||
event = &"jump"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="Hugging" type="Node" parent="StateChart/Root/Movement/OnWall"]
|
||||
script = ExtResource("27_34snm")
|
||||
|
||||
@@ -729,6 +743,12 @@ delay_in_seconds = "0.0"
|
||||
[node name="RunningCoyoteEnabled" type="Node" parent="StateChart/Root/Movement/OnWall"]
|
||||
script = ExtResource("27_34snm")
|
||||
|
||||
[node name="OnJump" type="Node" parent="StateChart/Root/Movement/OnWall/RunningCoyoteEnabled"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../../Jump/DoubleJump")
|
||||
event = &"jump"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="OnExpiration" type="Node" parent="StateChart/Root/Movement/OnWall/RunningCoyoteEnabled"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../Running")
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Godot;
|
||||
using GodotStateCharts;
|
||||
using Movementtests.addons.godot_state_charts.csharp;
|
||||
@@ -15,7 +14,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
MoveCamera,
|
||||
None,
|
||||
}
|
||||
private bool _isUsingGamepad = false;
|
||||
private bool _isUsingGamepad;
|
||||
|
||||
// User API to important child nodes.
|
||||
public HeadSystem HeadSystem;
|
||||
@@ -38,9 +37,11 @@ public partial class PlayerController : CharacterBody3D
|
||||
|
||||
private bool _movementEnabled = true;
|
||||
|
||||
private Vector3 _dashDirection = Vector3.Zero;
|
||||
|
||||
private bool _shouldMantle;
|
||||
private Vector3 _mantleLocation = Vector3.Zero;
|
||||
private Vector3 _dashDirection = Vector3.Zero;
|
||||
private Vector3 _preMantleVelocity = Vector3.Zero;
|
||||
|
||||
private float _lastFrameWasOnFloor = -Mathf.Inf;
|
||||
|
||||
@@ -196,9 +197,11 @@ public partial class PlayerController : CharacterBody3D
|
||||
private StateChartState _grounded;
|
||||
private StateChartState _airborne;
|
||||
private StateChartState _coyoteEnabled;
|
||||
private StateChartState _doubleJumpEnabled;
|
||||
private StateChartState _simpleJump;
|
||||
private StateChartState _doubleJump;
|
||||
private StateChartState _megaJump;
|
||||
private StateChartState _mantling;
|
||||
private StateChartState _simpleDash;
|
||||
private StateChartState _poweredDash;
|
||||
private StateChartState _aimedDash;
|
||||
@@ -208,7 +211,9 @@ public partial class PlayerController : CharacterBody3D
|
||||
private StateChartState _onWallHanging;
|
||||
private StateChartState _onWallRunning;
|
||||
private StateChartState _onWallRunningCoyoteEnabled;
|
||||
|
||||
|
||||
private Transition _onJumpFromWallCoyote;
|
||||
private Transition _onJumpFromWallRunCoyote;
|
||||
private Transition _onJumpFromWall1;
|
||||
private Transition _onJumpFromWall2;
|
||||
private Transition _onJumpFromWall3;
|
||||
@@ -252,9 +257,9 @@ public partial class PlayerController : CharacterBody3D
|
||||
Node3D cameraSmooth = GetNode<Node3D>("HeadSystem/CameraSmooth");
|
||||
|
||||
// Movement stuff
|
||||
WeaponRoot = GetNode<Node3D>("WeaponRoot");
|
||||
WeaponRoot = GetNode<Node3D>("WeaponRoot");
|
||||
WeaponSystem = GetNode<WeaponSystem>("WeaponRoot/WeaponSystem");
|
||||
MantleSystem = GetNode<MantleSystem>("MantleSystem");
|
||||
MantleSystem = GetNode<MantleSystem>("HeadSystem/MantleSystem");
|
||||
CapsuleCollider = GetNode<CapsuleCollider>("CapsuleCollider");
|
||||
DashSystem = GetNode<DashSystem>("DashSystem");
|
||||
StairsSystem = GetNode<StairsSystem>("StairsSystem");
|
||||
@@ -284,14 +289,18 @@ public partial class PlayerController : CharacterBody3D
|
||||
_empowerOn = StateChartState.Of(GetNode("StateChart/Root/Empower/On"));
|
||||
_powerExpired = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Expired"));
|
||||
_powerRecharging = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/AtLeastOneCharge"));
|
||||
_powerFull = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Full"));
|
||||
_powerFull = StateChartState.Of(GetNode("StateChart/Root/PowerReserve/Full"));
|
||||
|
||||
_grounded = StateChartState.Of(GetNode("StateChart/Root/Movement/Grounded"));
|
||||
_airborne = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne"));
|
||||
_coyoteEnabled = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne/CoyoteEnabled"));
|
||||
_doubleJumpEnabled = StateChartState.Of(GetNode("StateChart/Root/Movement/Airborne/DoubleJumpEnabled"));
|
||||
_simpleJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/SimpleJump"));
|
||||
_doubleJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/DoubleJump"));
|
||||
_megaJump = StateChartState.Of(GetNode("StateChart/Root/Movement/Jump/MegaJump"));
|
||||
_mantling = StateChartState.Of(GetNode("StateChart/Root/Movement/Mantling"));
|
||||
_onJumpFromWallCoyote = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/HuggingCoyoteEnabled/OnJump"));
|
||||
_onJumpFromWallRunCoyote = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/RunningCoyoteEnabled/OnJump"));
|
||||
_onJumpFromWall1 = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Hugging/OnJump"));
|
||||
_onJumpFromWall2 = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Hanging/OnJump"));
|
||||
_onJumpFromWall3 = Transition.Of(GetNode("StateChart/Root/Movement/OnWall/Running/OnJump"));
|
||||
@@ -362,6 +371,9 @@ public partial class PlayerController : CharacterBody3D
|
||||
_megaJump.StateEntered += OnMegaJumpStarted;
|
||||
_megaJump.StatePhysicsProcessing += HandleMegaJump;
|
||||
|
||||
_mantling.StateEntered += OnMantleStarted;
|
||||
_mantling.StatePhysicsProcessing += HandleMantling;
|
||||
|
||||
_simpleDash.StateEntered += OnSimpleDashStarted;
|
||||
_simpleDash.StatePhysicsProcessing += HandleSimpleDash;
|
||||
|
||||
@@ -383,7 +395,9 @@ public partial class PlayerController : CharacterBody3D
|
||||
_onWallRunningCoyoteEnabled.StateEntered += OnWallRunningStarted;
|
||||
_onWallRunningCoyoteEnabled.StatePhysicsProcessing += HandleWallRunning;
|
||||
_onWallRunning.StatePhysicsProcessing += HandleWallRunning;
|
||||
|
||||
|
||||
_onJumpFromWallCoyote.Taken += OnJumpFromWallCoyote;
|
||||
_onJumpFromWallRunCoyote.Taken += OnJumpFromWallCoyote;
|
||||
_onJumpFromWall1.Taken += OnJumpFromWall;
|
||||
_onJumpFromWall2.Taken += OnJumpFromWall;
|
||||
_onJumpFromWall3.Taken += OnJumpFromWall;
|
||||
@@ -478,7 +492,9 @@ public partial class PlayerController : CharacterBody3D
|
||||
|
||||
// If all else fail and we go down, we hug
|
||||
if (Velocity.Y < 0 && !_coyoteEnabled.Active)
|
||||
{
|
||||
_playerState.SendEvent("wall_hug");
|
||||
}
|
||||
}
|
||||
|
||||
public void OnWallHuggingStarted()
|
||||
@@ -509,6 +525,9 @@ public partial class PlayerController : CharacterBody3D
|
||||
|
||||
public void OnWallStarted()
|
||||
{
|
||||
if (!WallHugSystem.IsWallHugging())
|
||||
return;
|
||||
|
||||
_wallHugStartNormal = WallHugSystem.WallHugNormal.UnwrapOr(Vector3.Up);
|
||||
_currentWallContactPoint = WallHugSystem.WallHugLocation.UnwrapOr(Vector3.Zero);
|
||||
_wallHugStartLocation = _currentWallContactPoint + _wallHugStartNormal * _playerRadius;
|
||||
@@ -517,10 +536,6 @@ public partial class PlayerController : CharacterBody3D
|
||||
|
||||
public void OnWallStopped()
|
||||
{
|
||||
_wallHugStartLocation = Vector3.Zero;
|
||||
_currentWallContactPoint = Vector3.Zero;
|
||||
_wallHugStartNormal = Vector3.Zero;
|
||||
_wallHugStartProjectedVelocity = Vector3.Zero;
|
||||
}
|
||||
|
||||
public void HandleWallHugging(float delta)
|
||||
@@ -577,17 +592,12 @@ public partial class PlayerController : CharacterBody3D
|
||||
GlobalPosition = _wallHugStartLocation;
|
||||
}
|
||||
|
||||
private Option<Vector3> _plannedMantleLocation = Option<Vector3>.None;
|
||||
|
||||
// Jump
|
||||
public void OnInputJumpStarted()
|
||||
{
|
||||
if (CanMantle())
|
||||
if (MantleSystem.IsMantlePossible)
|
||||
{
|
||||
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);
|
||||
_playerState.SendEvent("mantle");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -596,7 +606,11 @@ public partial class PlayerController : CharacterBody3D
|
||||
_playerState.SendEvent("megajump");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (_onWallHuggingCoyoteEnabled.Active || _onWallRunningCoyoteEnabled.Active)
|
||||
{
|
||||
if (!_isWallJumpAvailable) return;
|
||||
}
|
||||
_playerState.SendEvent("jump");
|
||||
}
|
||||
|
||||
@@ -643,8 +657,14 @@ public partial class PlayerController : CharacterBody3D
|
||||
var currentHorizontalVelocity = new Vector2(Velocity.X, Velocity.Z);
|
||||
var wallJumpHorizontalVelocity = new Vector2(jumpVector.X, jumpVector.Z);
|
||||
|
||||
SetHorizontalVelocity(currentHorizontalVelocity + wallJumpHorizontalVelocity);;
|
||||
SetHorizontalVelocity(currentHorizontalVelocity + wallJumpHorizontalVelocity);
|
||||
}
|
||||
|
||||
public void OnJumpFromWallCoyote()
|
||||
{
|
||||
_isWallJumpAvailable = false;
|
||||
}
|
||||
|
||||
public void OnJumpFromWall()
|
||||
{
|
||||
ComputeJumpFromWallHSpeed(WallJumpStartVelocity);
|
||||
@@ -705,6 +725,36 @@ public partial class PlayerController : CharacterBody3D
|
||||
z: velocity.Y);
|
||||
}
|
||||
|
||||
public void OnMantleStarted()
|
||||
{
|
||||
HeadSystem.OnMantle();
|
||||
|
||||
_preMantleVelocity = Velocity;
|
||||
|
||||
var tween = GetTree().CreateTween();
|
||||
tween.SetTrans(Tween.TransitionType.Cubic);
|
||||
tween.SetEase(Tween.EaseType.InOut);
|
||||
var inbetweenDuration = MantleTime / MantleSystem.NumberOfValidPofiles;
|
||||
for (int i = 0; i < MantleSystem.NumberOfValidPofiles; i += 1)
|
||||
{
|
||||
var position = MantleSystem.WallProfilePositions[i];
|
||||
tween.TweenProperty(this, "global_position", position, inbetweenDuration);
|
||||
}
|
||||
|
||||
tween.Finished += MantleFinished;
|
||||
}
|
||||
|
||||
public void HandleMantling(float delta)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void MantleFinished()
|
||||
{
|
||||
Velocity = _preMantleVelocity;
|
||||
_playerState.SendEvent("grounded");
|
||||
}
|
||||
|
||||
public void HandleJump(float delta, float gravityFactor, int hangFrames)
|
||||
{
|
||||
// Update horizontal velocity
|
||||
@@ -925,6 +975,11 @@ public partial class PlayerController : CharacterBody3D
|
||||
if (WeaponSystem.IsPlantedUnderPlatform())
|
||||
dashLocation += Vector3.Down * _playerHeight;
|
||||
|
||||
_wallHugStartNormal = WeaponSystem.PlantNormal;
|
||||
_currentWallContactPoint = WeaponSystem.PlantLocation;
|
||||
_wallHugStartLocation = dashLocation;
|
||||
_wallHugStartProjectedVelocity = Velocity.Slide(_wallHugStartNormal);
|
||||
|
||||
var dashTween = CreatePositionTween(dashLocation, AimedDashTime);
|
||||
dashTween.Finished += DashToPlantedWeaponTweenEnded;
|
||||
}
|
||||
@@ -946,7 +1001,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
|
||||
RecoverWeapon();
|
||||
|
||||
var resultingEvent = shouldDashToHanging ? "to_planted" : "dash_finished";
|
||||
var resultingEvent = shouldDashToHanging ? "dash_to_planted" : "dash_finished";
|
||||
_playerState.SendEvent(resultingEvent);
|
||||
}
|
||||
|
||||
@@ -1017,9 +1072,13 @@ public partial class PlayerController : CharacterBody3D
|
||||
{
|
||||
var postDashVelocity = _preDashVelocity.Length() > PostDashSpeed ? PostDashSpeed : _preDashVelocity.Length();
|
||||
Velocity = _dashDirection * postDashVelocity;
|
||||
|
||||
|
||||
if (_shouldMantleOnDashEnded)
|
||||
MantleToLocation(_mantleLocation);
|
||||
{
|
||||
// TODO update post dash mantle
|
||||
// MantleToLocation(_mantleLocation);
|
||||
GD.Print("update post dash mantle");
|
||||
}
|
||||
}
|
||||
|
||||
public void OnSimpleDashStarted()
|
||||
@@ -1059,9 +1118,6 @@ public partial class PlayerController : CharacterBody3D
|
||||
|
||||
public void OnPoweredDashFinished()
|
||||
{
|
||||
// Try mantling but don't know if this is useful
|
||||
// if (CanMantle())
|
||||
// MantleToLocation(MantleSystem.FindMantleForHeadRotation(HeadSystem.Rotation.Y).Unwrap());
|
||||
}
|
||||
|
||||
public void FinishPoweredDash()
|
||||
@@ -1099,28 +1155,6 @@ public partial class PlayerController : CharacterBody3D
|
||||
_playerState.SendEvent("coyote_expired");
|
||||
}
|
||||
|
||||
// Mantling
|
||||
public bool CanMantle()
|
||||
{
|
||||
var mantleLocationResult = MantleSystem.FindMantleForHeadRotation(HeadSystem.Rotation.Y);
|
||||
return mantleLocationResult.IsSome(out _);
|
||||
}
|
||||
|
||||
private Vector3 _preMantleVelocity = Vector3.Zero;
|
||||
public void MantleToLocation(Vector3 location)
|
||||
{
|
||||
HeadSystem.OnMantle();
|
||||
|
||||
_preMantleVelocity = Velocity;
|
||||
var mantleTween = CreatePositionTween(location, MantleTime);
|
||||
mantleTween.Finished += MantleFinished;
|
||||
}
|
||||
public void MantleFinished()
|
||||
{
|
||||
Velocity = _preMantleVelocity;
|
||||
_playerState.SendEvent("grounded");
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// Stateless logic ////////
|
||||
///////////////////////////
|
||||
@@ -1273,7 +1307,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
LookAround(delta);
|
||||
CameraModifications((float) delta);
|
||||
HandleStairs((float) delta);
|
||||
_plannedMantleLocation = MantleSystem.FindMantleForHeadRotation(HeadSystem.Rotation.Y);
|
||||
MantleSystem.ProcessMantle(_grounded.Active);
|
||||
|
||||
if (WeaponSystem.InHandState.Active)
|
||||
RotateWeaponWithPlayer();
|
||||
|
||||
Reference in New Issue
Block a user