gd: simple mantle

This commit is contained in:
2025-05-23 12:20:07 +02:00
parent 29d196acdf
commit db20eaac85
3 changed files with 36 additions and 28 deletions

View File

@ -10,4 +10,7 @@
<ItemGroup> <ItemGroup>
<Folder Include="addons\" /> <Folder Include="addons\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Include="RustyOptions" Version="0.10.1" />
</ItemGroup>
</Project> </Project>

View File

@ -1,4 +1,5 @@
using Godot; using Godot;
using RustyOptions;
namespace PolarBears.PlayerControllerAddon; namespace PolarBears.PlayerControllerAddon;
@ -22,7 +23,7 @@ public partial class MantleSystem: Node3D
_mantleCast3D = mantleCast3D; _mantleCast3D = mantleCast3D;
} }
public Vector3 CheckWallInFront() public Result<Vector3, string> CheckWallInFront()
{ {
_wallInFrontCast3D.SetRotation(new Vector3( _wallInFrontCast3D.SetRotation(new Vector3(
_wallInFrontCast3D.Rotation.X, _wallInFrontCast3D.Rotation.X,
@ -31,21 +32,17 @@ public partial class MantleSystem: Node3D
if (!_wallInFrontCast3D.IsColliding()) if (!_wallInFrontCast3D.IsColliding())
{ {
return Vector3.Zero; return Result.Err<Vector3, string>("No collision found");
} }
Vector3 collisionPoint = _wallInFrontCast3D.GetCollisionPoint(0); var collisionPoint = _wallInFrontCast3D.GetCollisionPoint(0);
Vector3 horizontalEndLocation = collisionPoint - _wallInFrontCast3D.GetCollisionNormal(0) * MantleEndLocationDistanceFromWall; var horizontalEndLocation = collisionPoint - _wallInFrontCast3D.GetCollisionNormal(0) * MantleEndLocationDistanceFromWall;
Vector3 shapeCastStartLocation = horizontalEndLocation + Vector3.Up * MantleHeightCastStart; var shapeCastStartLocation = horizontalEndLocation + Vector3.Up * MantleHeightCastStart;
_mantleCast3D.SetGlobalPosition(shapeCastStartLocation); _mantleCast3D.SetGlobalPosition(shapeCastStartLocation);
Vector3 targetLocation = Vector3.Down * MantleHeightCastStart + Vector3.Up * MaxStepHeight; var targetLocation = Vector3.Down * MantleHeightCastStart + Vector3.Up * MaxStepHeight;
_mantleCast3D.SetTargetPosition(targetLocation); _mantleCast3D.SetTargetPosition(targetLocation);
if (!_mantleCast3D.IsColliding()) return _mantleCast3D.IsColliding() ? Result.Ok(_mantleCast3D.GetCollisionPoint(0)) : Result.Err<Vector3, string>("No collision found");
{
return Vector3.Zero;
}
return _mantleCast3D.GetCollisionPoint(0);
} }
} }

View File

@ -123,8 +123,7 @@ public partial class PlayerController : CharacterBody3D
public override void _PhysicsProcess(double delta) public override void _PhysicsProcess(double delta)
{ {
MantleSystem.CheckWallInFront(); var mantleLocationResult = MantleSystem.CheckWallInFront();
if (isOnFloorCustom()) if (isOnFloorCustom())
{ {
_lastFrameWasOnFloor = Engine.GetPhysicsFrames(); _lastFrameWasOnFloor = Engine.GetPhysicsFrames();
@ -145,24 +144,33 @@ public partial class PlayerController : CharacterBody3D
bool isPlayerDead = HealthSystem.IsDead(); bool isPlayerDead = HealthSystem.IsDead();
// Handle Jumping // Handle Jumping
if (Input.IsActionJustPressed("jump") && isOnFloorCustom() if (Input.IsActionJustPressed("jump")
&& !doesCapsuleHaveCrouchingHeight && !isPlayerDead) && !doesCapsuleHaveCrouchingHeight
&& !isPlayerDead)
{ {
Velocity = new Vector3( if (mantleLocationResult.IsOk(out var mantleLocation))
x: Velocity.X, {
y: Gravity.CalculateJumpForce() * (float)delta, Position = mantleLocation;
z: Velocity.Z); }
} else if (isOnFloorCustom())
else if (Input.IsActionJustPressed("jump") && !isOnFloorCustom() {
&& !doesCapsuleHaveCrouchingHeight && !isPlayerDead && _canDoubleJump) Velocity = new Vector3(
{ x: Velocity.X,
_canDoubleJump = false; y: Gravity.CalculateJumpForce() * (float)delta,
Velocity = new Vector3( z: Velocity.Z);
x: Velocity.X, }
y: Gravity.CalculateJumpForce() * (float)delta * DoubleJumpSpeedFactor, else if (!isOnFloorCustom()
z: Velocity.Z); && _canDoubleJump)
{
_canDoubleJump = false;
Velocity = new Vector3(
x: Velocity.X,
y: Gravity.CalculateJumpForce() * (float)delta * DoubleJumpSpeedFactor,
z: Velocity.Z);
}
} }
bool isHeadTouchingCeiling = IsHeadTouchingCeiling(); bool isHeadTouchingCeiling = IsHeadTouchingCeiling();
bool doesCapsuleHaveDefaultHeight = CapsuleCollider.IsDefaultHeight(); bool doesCapsuleHaveDefaultHeight = CapsuleCollider.IsDefaultHeight();