cirnogodot/Scripts/Components/FSM/3DPlayer/IsoMovementModule.cs
2025-06-17 11:57:59 +02:00

102 lines
No EOL
3.2 KiB
C#

using Cirno.Scripts.Components.Actors;
using Godot;
namespace Cirno.Scripts.Components.FSM._3DPlayer;
public partial class IsoMovementModule : ModuleBase<PlayerState, CharacterBody3D>
{
[Export] public IsoPlayerStorageModule PlayerStorage { get; private set; }
[Export] private InputProvider _inputProvider;
[Export] public int Speed { get; set; } = 45;
[Export] public int StrafeSpeed { get; set; } = 35;
[Export] public float Acceleration = 8f;
[Export] public float Deceleration = 8f;
[Export] public float Gravity = -9.8f;
[Export] public float FallSpeed = 20f;
private bool _isStrafing;
private float _accelerationPerSecond;
private float _decelerationPerSecond;
public int MovementSpeed => _isStrafing ? StrafeSpeed : Speed;
private IStateMachine<PlayerState, CharacterBody3D> _stateMachine;
private CharacterBody3D MainObject => _stateMachine.MainObject;
public override void EnterState(PlayerState state)
{
_accelerationPerSecond = Speed / Acceleration;
_decelerationPerSecond = Speed / Deceleration;
}
public override void ExitState(PlayerState state)
{
}
public override void Init(IStateMachine<PlayerState, CharacterBody3D> machine)
{
_stateMachine = machine;
}
public override void Process(double delta)
{
var movementInput = _inputProvider.GetMovementInput();
_isStrafing = _inputProvider.GetStrafePressed();
var rightStickInput = _inputProvider.GetAimInput().Normalized();
// Update Facing Direction
// if (!_isStrafing)
// {
if (rightStickInput.Length() > 0.1f) // If the right stick is moved
{
PlayerStorage.FacingDirection = rightStickInput;
}
else if (movementInput != Vector2.Zero) // Fall back to movement direction
{
PlayerStorage.FacingDirection = movementInput;
}
// }
var rotatedMovementDirection = movementInput.Rotated(Mathf.DegToRad(-45f));
PlayerStorage.MovementDirection = new Vector3(rotatedMovementDirection.X, 0, rotatedMovementDirection.Y);
}
public override void PhysicsProcess(double delta)
{
var frameVelocity = MainObject.Velocity;
if (_isStrafing)
{
// Instant movement at strafe speed
frameVelocity = PlayerStorage.MovementDirection * StrafeSpeed;
}
else
{
Vector3 targetVelocity = PlayerStorage.MovementDirection * Speed;
if (PlayerStorage.MovementDirection != Vector3.Zero)
{
frameVelocity = frameVelocity.MoveToward(targetVelocity, Acceleration * (float)delta);
}
else
{
frameVelocity = frameVelocity.MoveToward(Vector3.Zero, Deceleration * (float)delta);
}
}
//MainObject.Velocity += _movementDirection * MovementSpeed;
var velocityY = Mathf.Clamp(frameVelocity.Y + Gravity * (float)delta, -FallSpeed, FallSpeed);
frameVelocity.Y = velocityY;
MainObject.Velocity = frameVelocity;
MainObject.MoveAndSlide();
}
}