gd: made wall jump more intuitive and act like a double jump
Some checks failed
Create tag and build when new code gets to main / BumpTag (push) Successful in 17s
Create tag and build when new code gets to main / Export (push) Failing after 1s

This commit is contained in:
2025-07-04 14:15:09 +02:00
parent cf98e6c36c
commit 767d0fc768
6 changed files with 50 additions and 20 deletions

View File

@ -199,6 +199,15 @@ script = ExtResource("26_infe6")
initial_state = NodePath("WeaponInHand") initial_state = NodePath("WeaponInHand")
metadata/_custom_type_script = "uid://c1vp0ojjvaby1" metadata/_custom_type_script = "uid://c1vp0ojjvaby1"
[node name="AimCanceled" type="Node" parent="StateChart/Root/Actions"]
script = ExtResource("27_34snm")
[node name="ToWeaponInHand" type="Node" parent="StateChart/Root/Actions/AimCanceled"]
script = ExtResource("28_n7qhm")
to = NodePath("../../WeaponInHand")
event = &"aim_released"
delay_in_seconds = "0.0"
[node name="WeaponInHand" type="Node" parent="StateChart/Root/Actions"] [node name="WeaponInHand" type="Node" parent="StateChart/Root/Actions"]
script = ExtResource("27_34snm") script = ExtResource("27_34snm")
@ -213,7 +222,7 @@ script = ExtResource("27_34snm")
[node name="ToWeaponInHand" type="Node" parent="StateChart/Root/Actions/Aiming"] [node name="ToWeaponInHand" type="Node" parent="StateChart/Root/Actions/Aiming"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../WeaponInHand") to = NodePath("../../AimCanceled")
event = &"aim_canceled" event = &"aim_canceled"
delay_in_seconds = "0.0" delay_in_seconds = "0.0"
@ -424,10 +433,10 @@ delay_in_seconds = "0.0"
[node name="JumpFromWall" type="Node" parent="StateChart/Root/Movement/Airborne"] [node name="JumpFromWall" type="Node" parent="StateChart/Root/Movement/Airborne"]
script = ExtResource("27_34snm") script = ExtResource("27_34snm")
[node name="ToDoubleJump" type="Node" parent="StateChart/Root/Movement/Airborne/JumpFromWall"] [node name="JumpedFromWall" type="Node" parent="StateChart/Root/Movement/Airborne/JumpFromWall"]
script = ExtResource("28_n7qhm") script = ExtResource("28_n7qhm")
to = NodePath("../../DoubleJumpEnabled") to = NodePath("../../Falling")
event = &"to_double_jump" event = &"jump_from_wall"
delay_in_seconds = "0.0" delay_in_seconds = "0.0"
[node name="ToFalling" type="Node" parent="StateChart/Root/Movement/Airborne/JumpFromWall"] [node name="ToFalling" type="Node" parent="StateChart/Root/Movement/Airborne/JumpFromWall"]

View File

@ -12,6 +12,8 @@ public partial class Gravity: Node3D
public float DoubleJumpSpeedFactor { get; set; } = 2f; public float DoubleJumpSpeedFactor { get; set; } = 2f;
[Export(PropertyHint.Range, "0.1,10,0.1,or_greater")] [Export(PropertyHint.Range, "0.1,10,0.1,or_greater")]
public float JumpFromDashSpeedFactor { get; set; } = 2f; public float JumpFromDashSpeedFactor { get; set; } = 2f;
[Export(PropertyHint.Range, "0.1,10,0.1,or_greater")]
public float JumpFromWallSpeedFactor { get; set; } = 2f;
[Export(PropertyHint.Range, "0,1,0.01,or_greater")] [Export(PropertyHint.Range, "0,1,0.01,or_greater")]
public float AdditionalGravityPower { get; set; } = 1f; public float AdditionalGravityPower { get; set; } = 1f;
@ -24,6 +26,7 @@ public partial class Gravity: Node3D
public float CalculateJumpForce() => _gravity * (StartVelocity / AdditionalGravityPower); public float CalculateJumpForce() => _gravity * (StartVelocity / AdditionalGravityPower);
public float CalculateJumpFromDashForce() => CalculateJumpForce() * JumpFromDashSpeedFactor; public float CalculateJumpFromDashForce() => CalculateJumpForce() * JumpFromDashSpeedFactor;
public float CalculateJumpFromWallForce() => CalculateJumpForce() * JumpFromWallSpeedFactor;
public float CalculateDoubleJumpForce() => CalculateJumpForce() * DoubleJumpSpeedFactor; public float CalculateDoubleJumpForce() => CalculateJumpForce() * DoubleJumpSpeedFactor;
public float CalculateGravityForce() => _gravity * Weight; public float CalculateGravityForce() => _gravity * Weight;
} }

View File

@ -55,6 +55,8 @@ public partial class PlayerController : CharacterBody3D
public int DashActionsLeft { get; set; } public int DashActionsLeft { get; set; }
private bool _isWallJumpAvailable = true;
private StateChart _playerState; private StateChart _playerState;
// Actions state // Actions state
private StateChartState _weaponInHand; private StateChartState _weaponInHand;
@ -275,6 +277,7 @@ public partial class PlayerController : CharacterBody3D
public void OnGrounded() public void OnGrounded()
{ {
DashActionsLeft = MaxNumberOfDashActions; DashActionsLeft = MaxNumberOfDashActions;
_isWallJumpAvailable = true;
} }
public bool CanPerformDashAction() public bool CanPerformDashAction()
@ -284,6 +287,7 @@ public partial class PlayerController : CharacterBody3D
public void PerformDashAction() public void PerformDashAction()
{ {
_isWallJumpAvailable = true;
_dashCooldownTimer.Start(); _dashCooldownTimer.Start();
DashActionsLeft--; DashActionsLeft--;
} }
@ -303,24 +307,30 @@ public partial class PlayerController : CharacterBody3D
{ {
_playerState.SendEvent("jump_from_dash"); _playerState.SendEvent("jump_from_dash");
PerformDashAction(); PerformDashAction();
PerformJump(MoveSystem.JumpTypes.JUMP_FROM_DASH); PerformJump(MoveSystem.JumpTypes.JumpFromDash);
return; return;
} }
_playerState.SendEvent("to_double_jump"); _playerState.SendEvent("to_double_jump");
PerformJump(MoveSystem.JumpTypes.SIMPLE_JUMP); PerformJump(MoveSystem.JumpTypes.SimpleJump);
} }
public void JumpFromWall() public void JumpFromWall()
{ {
if (!_isWallJumpAvailable)
return;
_isWallJumpAvailable = false;
var wallNormal = WallHugSystem.GetWallNormal().UnwrapOr(Vector3.Up); var wallNormal = WallHugSystem.GetWallNormal().UnwrapOr(Vector3.Up);
var isLookingTowardsWall = HeadSystem.GetForwardHorizontalVector().Dot(wallNormal) > 0.7;
var jumpDirection = isLookingTowardsWall ? Vector3.Up : wallNormal;
if (_aiming.Active && CanPerformDashAction()) if (_aiming.Active && CanPerformDashAction())
{ {
_playerState.SendEvent("jump_from_dash"); _playerState.SendEvent("jump_from_dash");
PerformDashAction(); PerformDashAction();
PerformJump(MoveSystem.JumpTypes.JUMP_FROM_DASH, wallNormal); PerformJump(MoveSystem.JumpTypes.JumpFromDash, jumpDirection);
return; return;
} }
_playerState.SendEvent("to_double_jump"); _playerState.SendEvent("jump_from_wall");
PerformJump(MoveSystem.JumpTypes.SIMPLE_JUMP, wallNormal); PerformJump(MoveSystem.JumpTypes.JumpFromWall, jumpDirection);
} }
public void DoubleJump() public void DoubleJump()
{ {
@ -328,10 +338,10 @@ public partial class PlayerController : CharacterBody3D
if (_aiming.Active && CanPerformDashAction()) if (_aiming.Active && CanPerformDashAction())
{ {
PerformDashAction(); PerformDashAction();
PerformJump(MoveSystem.JumpTypes.JUMP_FROM_DASH); PerformJump(MoveSystem.JumpTypes.JumpFromDash);
return; return;
} }
PerformJump(MoveSystem.JumpTypes.DOUBLE_JUMP); PerformJump(MoveSystem.JumpTypes.DoubleJump);
} }
private void PerformJump(MoveSystem.JumpTypes jumpType, Vector3? jumpDirection = null) private void PerformJump(MoveSystem.JumpTypes jumpType, Vector3? jumpDirection = null)
{ {
@ -341,8 +351,8 @@ public partial class PlayerController : CharacterBody3D
var proportionOfTimeGone = _timeAfterDashingTimer.TimeLeft / _timeAfterDashingTimer.WaitTime; var proportionOfTimeGone = _timeAfterDashingTimer.TimeLeft / _timeAfterDashingTimer.WaitTime;
var actualBoost = 1 + MaxJumpBoostAfterDashing * proportionOfTimeGone; var actualBoost = 1 + MaxJumpBoostAfterDashing * proportionOfTimeGone;
var makeItDouble = actualBoost > 1; var makeItDouble = actualBoost > 1;
if (makeItDouble && jumpType == MoveSystem.JumpTypes.SIMPLE_JUMP) if (makeItDouble && jumpType == MoveSystem.JumpTypes.SimpleJump)
jumpType = MoveSystem.JumpTypes.DOUBLE_JUMP; // convert simple jump to double if done right after a dash jumpType = MoveSystem.JumpTypes.DoubleJump; // convert simple jump to double if done right after a dash
_timeAfterDashingTimer.Stop(); _timeAfterDashingTimer.Stop();
bool doesCapsuleHaveCrouchingHeight = CapsuleCollider.IsCrouchingHeight(); bool doesCapsuleHaveCrouchingHeight = CapsuleCollider.IsCrouchingHeight();

View File

@ -29,4 +29,9 @@ public partial class HeadSystem : Node3D
_camera.Rotation = currentCameraRotation; _camera.Rotation = currentCameraRotation;
} }
public Vector3 GetForwardHorizontalVector()
{
return GetGlobalTransform().Basis.Z;
}
} }

View File

@ -8,9 +8,10 @@ public partial class MoveSystem : Node3D
{ {
public enum JumpTypes public enum JumpTypes
{ {
SIMPLE_JUMP, SimpleJump,
DOUBLE_JUMP, DoubleJump,
JUMP_FROM_DASH JumpFromDash,
JumpFromWall
} }
public record MoveSystemParameters( public record MoveSystemParameters(
@ -196,15 +197,18 @@ public partial class MoveSystem : Node3D
var jumpForce = 0.0f; var jumpForce = 0.0f;
switch (jumpType) switch (jumpType)
{ {
case JumpTypes.DOUBLE_JUMP: case JumpTypes.DoubleJump:
jumpForce = _gravity.CalculateDoubleJumpForce(); jumpForce = _gravity.CalculateDoubleJumpForce();
break; break;
case JumpTypes.SIMPLE_JUMP: case JumpTypes.SimpleJump:
jumpForce = _gravity.CalculateJumpForce(); jumpForce = _gravity.CalculateJumpForce();
break; break;
case JumpTypes.JUMP_FROM_DASH: case JumpTypes.JumpFromDash:
jumpForce = _gravity.CalculateJumpFromDashForce(); jumpForce = _gravity.CalculateJumpFromDashForce();
break; break;
case JumpTypes.JumpFromWall:
jumpForce = _gravity.CalculateJumpFromWallForce();
break;
default: default:
jumpForce = _gravity.CalculateJumpForce(); jumpForce = _gravity.CalculateJumpForce();
break; break;

View File

@ -74,7 +74,6 @@ public partial class WeaponSystem : RigidBody3D
Freeze = true; Freeze = true;
GlobalPosition = PlantLocation; GlobalPosition = PlantLocation;
LookAt(GlobalTransform.Origin + PlantNormal, Vector3.Up, true); LookAt(GlobalTransform.Origin + PlantNormal, Vector3.Up, true);
GD.Print(GlobalRotation);
} }
public void OnThrownWeaponReachesGround(Node other) public void OnThrownWeaponReachesGround(Node other)