gd: game feel improvement, dash limit, improved jump while aiming for dash
This commit is contained in:
@ -34,13 +34,16 @@
|
||||
[ext_resource type="PackedScene" uid="uid://ckm3d6k08a72u" path="res://systems/weapon/weapon.tscn" id="29_wv70j"]
|
||||
|
||||
[sub_resource type="CapsuleMesh" id="CapsuleMesh_xc2g5"]
|
||||
height = 1.7
|
||||
|
||||
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_wydro"]
|
||||
height = 1.7
|
||||
|
||||
[node name="Player" type="CharacterBody3D"]
|
||||
script = ExtResource("1_poq2x")
|
||||
TimeScaleAimInAir = 0.15
|
||||
MaxJumpBoostAfterDashing = 1.4
|
||||
MaxJumpBoostAfterDashing = 0.7
|
||||
MaxNumberOfDashActions = 3
|
||||
|
||||
[node name="InputController" type="Node3D" parent="."]
|
||||
script = ExtResource("16_v31n3")
|
||||
@ -56,16 +59,18 @@ hit = ExtResource("11_cresl")
|
||||
drop = ExtResource("12_34snm")
|
||||
|
||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0)
|
||||
visible = false
|
||||
mesh = SubResource("CapsuleMesh_xc2g5")
|
||||
|
||||
[node name="CapsuleCollider" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.85, 0)
|
||||
shape = SubResource("CapsuleShape3D_wydro")
|
||||
script = ExtResource("8_lmtjd")
|
||||
CapsuleDefaultHeight = 1.7
|
||||
|
||||
[node name="HeadSystem" parent="." instance=ExtResource("11_rxwoh")]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.68, 0)
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.6, 0)
|
||||
|
||||
[node name="HealthSystem" type="Node3D" parent="."]
|
||||
script = ExtResource("5_umw0l")
|
||||
@ -85,10 +90,12 @@ target_position = Vector3(0, -0.75, 0)
|
||||
|
||||
[node name="MantleSystem" parent="." instance=ExtResource("8_qu4wy")]
|
||||
MantleEndLocationDistanceFromWall = 0.3
|
||||
MantleHeightCastStart = 2.0
|
||||
MantleHeightCastStart = 1.5
|
||||
|
||||
[node name="Bobbing" type="Node3D" parent="."]
|
||||
script = ExtResource("10_7wk1w")
|
||||
BobbingFrequency = 3.0
|
||||
BobbingAmplitude = 0.05
|
||||
|
||||
[node name="FieldOfView" type="Node3D" parent="."]
|
||||
script = ExtResource("12_m2mxi")
|
||||
@ -113,14 +120,15 @@ target_position = Vector3(0, 1, 0)
|
||||
|
||||
[node name="MoveSystem" type="Node3D" parent="."]
|
||||
script = ExtResource("20_rxwoh")
|
||||
WalkSpeed = 10.0
|
||||
SprintSpeed = 15.0
|
||||
DoubleJumpSpeedFactor = 1.4
|
||||
WalkSpeed = 7.2
|
||||
DecelerationSpeedFactorFloor = 7.0
|
||||
ApexHoldTime = 0.1
|
||||
|
||||
[node name="Gravity" type="Node3D" parent="."]
|
||||
script = ExtResource("9_lsueh")
|
||||
Weight = 6.5
|
||||
StartVelocity = 4.0
|
||||
Weight = 3.5
|
||||
StartVelocity = 0.7
|
||||
JumpFromDashSpeedFactor = 4.0
|
||||
|
||||
[node name="TweenQueueSystem" parent="." instance=ExtResource("22_rpwev")]
|
||||
|
||||
@ -173,7 +181,6 @@ offset_left = 1530.0
|
||||
offset_top = 1.0
|
||||
offset_right = -2.0
|
||||
offset_bottom = 1.0
|
||||
enabled = false
|
||||
initial_node_to_watch = NodePath("../StateChart")
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
@ -373,6 +380,12 @@ to = NodePath("../../DoubleJumpEnabled")
|
||||
event = &"to_double_jump"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="ToFalling" type="Node" parent="StateChart/Root/Movement/Airborne/Jump"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../Falling")
|
||||
event = &"jump_from_dash"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="JumpFromWall" type="Node" parent="StateChart/Root/Movement/Airborne"]
|
||||
script = ExtResource("27_34snm")
|
||||
|
||||
@ -382,6 +395,12 @@ to = NodePath("../../DoubleJumpEnabled")
|
||||
event = &"to_double_jump"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="ToFalling" type="Node" parent="StateChart/Root/Movement/Airborne/JumpFromWall"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../Falling")
|
||||
event = &"jump_from_dash"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="DoubleJumpEnabled" type="Node" parent="StateChart/Root/Movement/Airborne"]
|
||||
script = ExtResource("27_34snm")
|
||||
|
||||
@ -403,6 +422,12 @@ delay_in_seconds = "0.0"
|
||||
[node name="Falling" type="Node" parent="StateChart/Root/Movement/Airborne"]
|
||||
script = ExtResource("27_34snm")
|
||||
|
||||
[node name="ToDoubleJump" type="Node" parent="StateChart/Root/Movement/Airborne/Falling"]
|
||||
script = ExtResource("28_n7qhm")
|
||||
to = NodePath("../../DoubleJumpEnabled")
|
||||
event = &"enable_double_jump"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[connection signal="input_aim_canceled" from="InputController" to="." method="OnInputAimCanceled"]
|
||||
[connection signal="input_aim_pressed" from="InputController" to="." method="OnInputAimPressed"]
|
||||
[connection signal="input_aim_released" from="InputController" to="." method="OnInputAimReleased"]
|
||||
|
@ -4,12 +4,16 @@ namespace Movementtests.player_controller.Scripts;
|
||||
|
||||
public partial class Gravity: Node3D
|
||||
{
|
||||
[Export(PropertyHint.Range, "0,100,0.1,or_greater")]
|
||||
public float Weight { get; set; } = 70.0f;
|
||||
[Export(PropertyHint.Range, "0,20,0.1,or_greater")]
|
||||
public float StartVelocity { get; set; } = 3.0f;
|
||||
[Export(PropertyHint.Range, "0.01,10,0.01,or_greater")]
|
||||
public float AdditionalGravityPower { get; set; } = 2f;
|
||||
[Export(PropertyHint.Range, "0,10,0.01,or_greater")]
|
||||
public float Weight { get; set; } = 3.0f;
|
||||
[Export(PropertyHint.Range, "0,2,0.01,or_greater")]
|
||||
public float StartVelocity { get; set; } = 1.0f;
|
||||
[Export(PropertyHint.Range, "0.1,10,0.1,or_greater")]
|
||||
public float DoubleJumpSpeedFactor { get; set; } = 2f;
|
||||
[Export(PropertyHint.Range, "0.1,10,0.1,or_greater")]
|
||||
public float JumpFromDashSpeedFactor { get; set; } = 2f;
|
||||
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
||||
public float AdditionalGravityPower { get; set; } = 1f;
|
||||
|
||||
private float _gravity;
|
||||
|
||||
@ -19,5 +23,7 @@ public partial class Gravity: Node3D
|
||||
}
|
||||
|
||||
public float CalculateJumpForce() => _gravity * (StartVelocity / AdditionalGravityPower);
|
||||
public float CalculateJumpFromDashForce() => CalculateJumpForce() * JumpFromDashSpeedFactor;
|
||||
public float CalculateDoubleJumpForce() => CalculateJumpForce() * DoubleJumpSpeedFactor;
|
||||
public float CalculateGravityForce() => _gravity * Weight;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ using Godot;
|
||||
using GodotStateCharts;
|
||||
using Movementtests.systems;
|
||||
using Movementtests.player_controller.Scripts;
|
||||
using RustyOptions;
|
||||
|
||||
public partial class PlayerController : CharacterBody3D
|
||||
{
|
||||
@ -38,17 +39,19 @@ public partial class PlayerController : CharacterBody3D
|
||||
private float _inputRotateY;
|
||||
private float _inputRotateFloorplane;
|
||||
|
||||
private bool _isAiming;
|
||||
private bool _dashCanceled;
|
||||
|
||||
private Timer _coyoteTimer;
|
||||
private Timer _timeScaleAimInAirTimer;
|
||||
private Timer _timeAfterDashingTimer;
|
||||
[Export(PropertyHint.Range, "0,1,0.01,or_greater")]
|
||||
public float TimeScaleAimInAir { get; set; } = 0.2f;
|
||||
[Export(PropertyHint.Range, "1,5,0.1,or_greater")]
|
||||
public float MaxJumpBoostAfterDashing { get; set; } = 2f;
|
||||
[Export(PropertyHint.Range, "0,5,0.1,or_greater")]
|
||||
public float MaxJumpBoostAfterDashing { get; set; } = 1f;
|
||||
|
||||
[Export(PropertyHint.Range, "0,5,1,or_greater")]
|
||||
public int MaxNumberOfDashActions { get; set; } = 1;
|
||||
|
||||
public int DashActionsLeft { get; set; }
|
||||
|
||||
private StateChart _playerState;
|
||||
// Actions state
|
||||
private StateChartState _weaponInHand;
|
||||
@ -177,6 +180,8 @@ public partial class PlayerController : CharacterBody3D
|
||||
};
|
||||
HealthSystem.Init(healthSystemParams);
|
||||
Stamina.SetSpeeds(MoveSystem.WalkSpeed, MoveSystem.SprintSpeed);
|
||||
|
||||
DashActionsLeft = MaxNumberOfDashActions;
|
||||
|
||||
///////////////////////////
|
||||
// Signal setup ///////////
|
||||
@ -188,7 +193,8 @@ public partial class PlayerController : CharacterBody3D
|
||||
_aiming.StateProcessing += HandleAiming;
|
||||
_aiming.StateEntered += OnAimingEntered;
|
||||
_aiming.StateExited += ResetTimeScale;
|
||||
|
||||
|
||||
_grounded.StateEntered += OnGrounded;
|
||||
_grounded.StatePhysicsProcessing += HandleGrounded;
|
||||
_airborne.StatePhysicsProcessing += HandleAirborne;
|
||||
_wallHugging.StatePhysicsProcessing += HandleWallHugging;
|
||||
@ -256,6 +262,24 @@ public partial class PlayerController : CharacterBody3D
|
||||
///////////////////////////
|
||||
// Stateful logic /////////
|
||||
///////////////////////////
|
||||
|
||||
// Simple states
|
||||
public void OnGrounded()
|
||||
{
|
||||
DashActionsLeft = MaxNumberOfDashActions;
|
||||
GD.Print(DashActionsLeft);
|
||||
}
|
||||
|
||||
public bool CanPerformDashAction()
|
||||
{
|
||||
return DashActionsLeft > 0;
|
||||
}
|
||||
|
||||
public void PerformDashAction()
|
||||
{
|
||||
DashActionsLeft--;
|
||||
GD.Print(DashActionsLeft);
|
||||
}
|
||||
|
||||
// Jumping
|
||||
public void StartCoyoteTime()
|
||||
@ -268,36 +292,56 @@ public partial class PlayerController : CharacterBody3D
|
||||
}
|
||||
public void Jump()
|
||||
{
|
||||
if (_aiming.Active && CanPerformDashAction())
|
||||
{
|
||||
_playerState.SendEvent("jump_from_dash");
|
||||
PerformDashAction();
|
||||
PerformJump(MoveSystem.JumpTypes.JUMP_FROM_DASH);
|
||||
return;
|
||||
}
|
||||
_playerState.SendEvent("to_double_jump");
|
||||
PerformJump(false);
|
||||
PerformJump(MoveSystem.JumpTypes.SIMPLE_JUMP);
|
||||
}
|
||||
public void JumpFromWall()
|
||||
{
|
||||
var wallNormal = WallHugSystem.GetWallNormal().UnwrapOr(Vector3.Up);
|
||||
if (_aiming.Active && CanPerformDashAction())
|
||||
{
|
||||
_playerState.SendEvent("jump_from_dash");
|
||||
PerformDashAction();
|
||||
PerformJump(MoveSystem.JumpTypes.JUMP_FROM_DASH, wallNormal);
|
||||
return;
|
||||
}
|
||||
_playerState.SendEvent("to_double_jump");
|
||||
var wallNormal = WallHugSystem.GetWallNormal();
|
||||
if (wallNormal.IsSome(out var normal))
|
||||
PerformJump(false, normal);
|
||||
PerformJump(false);
|
||||
PerformJump(MoveSystem.JumpTypes.SIMPLE_JUMP, wallNormal);
|
||||
}
|
||||
public void DoubleJump()
|
||||
{
|
||||
_playerState.SendEvent("to_falling");
|
||||
PerformJump(true);
|
||||
if (_aiming.Active && CanPerformDashAction())
|
||||
{
|
||||
PerformDashAction();
|
||||
PerformJump(MoveSystem.JumpTypes.JUMP_FROM_DASH);
|
||||
return;
|
||||
}
|
||||
PerformJump(MoveSystem.JumpTypes.DOUBLE_JUMP);
|
||||
}
|
||||
private void PerformJump(bool isDoubleJump, Vector3? jumpDirection = null)
|
||||
private void PerformJump(MoveSystem.JumpTypes jumpType, Vector3? jumpDirection = null)
|
||||
{
|
||||
var effectiveJumpDirection = jumpDirection ?? Vector3.Up;
|
||||
var jumpVector = (effectiveJumpDirection.Normalized() + Vector3.Up).Normalized();
|
||||
|
||||
var proportionOfTimeGone = _timeAfterDashingTimer.TimeLeft / _timeAfterDashingTimer.WaitTime;
|
||||
GD.Print(proportionOfTimeGone);
|
||||
var actualBoost = 1 + MaxJumpBoostAfterDashing * proportionOfTimeGone;
|
||||
var makeItDouble = actualBoost > 1;
|
||||
if (makeItDouble && jumpType == MoveSystem.JumpTypes.SIMPLE_JUMP)
|
||||
jumpType = MoveSystem.JumpTypes.DOUBLE_JUMP; // convert simple jump to double if done right after a dash
|
||||
_timeAfterDashingTimer.Stop();
|
||||
|
||||
bool doesCapsuleHaveCrouchingHeight = CapsuleCollider.IsCrouchingHeight();
|
||||
bool isPlayerDead = HealthSystem.IsDead();
|
||||
if (!doesCapsuleHaveCrouchingHeight && !isPlayerDead)
|
||||
MoveSystem.Jump(isDoubleJump, jumpVector, (float) actualBoost);
|
||||
MoveSystem.Jump(jumpType, jumpVector, (float) actualBoost);
|
||||
}
|
||||
|
||||
// Mantling
|
||||
@ -315,6 +359,15 @@ public partial class PlayerController : CharacterBody3D
|
||||
// Dashing and weapon throwing
|
||||
public void OnDashStarted()
|
||||
{
|
||||
if (!CanPerformDashAction())
|
||||
{
|
||||
_playerState.SendEvent("aim_canceled");
|
||||
_playerState.SendEvent("dash_ended");
|
||||
DashSystem.CancelDash();
|
||||
return;
|
||||
}
|
||||
|
||||
PerformDashAction();
|
||||
_timeAfterDashingTimer.Start();
|
||||
if (WeaponSystem.FlyingState.Active)
|
||||
{
|
||||
@ -330,6 +383,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
}
|
||||
public void OnDashEnded()
|
||||
{
|
||||
// _playerState.SendEvent("enable_double_jump"); // Allow for double jump after dash -- OP ?
|
||||
// Regular dash
|
||||
if (WeaponSystem.InHandState.Active)
|
||||
{
|
||||
@ -379,7 +433,7 @@ public partial class PlayerController : CharacterBody3D
|
||||
}
|
||||
public void OnAimingEntered()
|
||||
{
|
||||
if (!isOnFloorCustom())
|
||||
if (!isOnFloorCustom() && CanPerformDashAction())
|
||||
ReduceTimeScaleWhileAiming();
|
||||
}
|
||||
|
||||
@ -391,10 +445,15 @@ public partial class PlayerController : CharacterBody3D
|
||||
public void HandleAiming(float delta)
|
||||
{
|
||||
RotateWeaponWithPlayer();
|
||||
DashSystem.PrepareDash();
|
||||
|
||||
if (isOnFloorCustom())
|
||||
ResetTimeScale();
|
||||
if (CanPerformDashAction())
|
||||
DashSystem.PrepareDash();
|
||||
else
|
||||
{
|
||||
_playerState.SendEvent("aim_canceled");
|
||||
DashSystem.CancelDash();
|
||||
}
|
||||
}
|
||||
|
||||
// Physics processes
|
||||
|
Reference in New Issue
Block a user