ludumdare50/Assets/Scripts/PlayerMovement.cs
2022-04-02 01:12:35 -04:00

88 lines
2.4 KiB
C#

#nullable enable
using JetBrains.Annotations;
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(PlayerInput), typeof(Rigidbody2D))]
public class PlayerMovement : MonoBehaviour {
[SerializeField] PlayerStats playerStats;
Rigidbody2D rb;
PlayerInput playerInput;
Vector2 moveDirection;
BaseState currentState = new NormalMovementState();
void Awake() {
rb = GetComponent<Rigidbody2D>();
playerInput = GetComponent<PlayerInput>();
}
void FixedUpdate() {
if (currentState.FixedUpdateState(this) is {} newState)
SwitchState(newState);
}
public void OnMove(InputAction.CallbackContext ctx) {
moveDirection = ctx.ReadValue<Vector2>();
if (moveDirection.sqrMagnitude > 1.0f)
moveDirection.Normalize();
}
public void OnJump(InputAction.CallbackContext ctx) {
if (!ctx.ReadValueAsButton())
return;
SwitchState(new JumpingMovementState());
}
void SwitchState(BaseState newState) {
currentState.LeaveState(this);
currentState = newState;
newState.EnterState(this);
}
class BaseState {
//TODO If we never do anything before enter, replace with constructor?
public virtual void EnterState(PlayerMovement playerMovement) {}
public virtual void LeaveState(PlayerMovement playerMovement) {}
[CanBeNull]
public virtual BaseState UpdateState(PlayerMovement playerMovement) => null;
[CanBeNull]
public virtual BaseState FixedUpdateState(PlayerMovement playerMovement) => null;
}
class NormalMovementState : BaseState {
public override BaseState FixedUpdateState(PlayerMovement playerMovement) {
playerMovement.rb.velocity = (Vector3)playerMovement.moveDirection * playerMovement.playerStats.movementSpeed;
return null;
}
}
class JumpingMovementState : BaseState {
Vector3 startPosition;
float startTime;
public override void EnterState(PlayerMovement playerMovement) {
startPosition = playerMovement.transform.position;
startTime = Time.time;
}
public override BaseState FixedUpdateState(PlayerMovement playerMovement) {
float currentTime = Time.time - startTime;
if (currentTime >= playerMovement.playerStats.safeZoneJumpDuration)
return new NormalMovementState();
playerMovement.rb.MovePosition(Vector3.Lerp(
startPosition,
playerMovement.playerStats.safeZonePosition,
currentTime / playerMovement.playerStats.safeZoneJumpDuration
));
return null;
}
}
}