using System; using System.Collections.Generic; using Management; using UnityEngine; using UnityEngine.InputSystem; namespace Player { [RequireComponent(typeof(Rigidbody2D))] public class Movement : MonoBehaviour { private static readonly int Spring = Animator.StringToHash("spring"); [SerializeField] private float runSpeed; [SerializeField] private float springPower; [SerializeField] private float jumpForce; [SerializeField] private float airJumpForce; [SerializeField] private SpriteRenderer spriteRenderer; [SerializeField] private float turnDelay; [SerializeField] private InputActionReference interactReference; private Animator _springAnimator; private Rigidbody2D _rb; private bool _grounded = true; private bool _facingLeft; private float _turnDelayTimer; private float _groundedCheckTimer; private bool _interact; private int _airJumpCharges; private bool _jumpPressedThisFrame = true; private bool _fireSpring; private bool _jump; private bool _airJump; private Vector2 _airJumpDir; private bool _autoDrive = true; private void Awake() { _rb = GetComponent(); InputSystem.actions.FindActionMap("UI").Disable(); InputSystem.actions.FindActionMap("Player").Enable(); interactReference.action.performed += HandleInteraction; interactReference.action.canceled += HandleInteraction; } private void Start() { Cursor.lockState = CursorLockMode.None; Cursor.visible = true; } private void HandleInteraction(InputAction.CallbackContext obj) { _interact = obj.ReadValueAsButton(); _jumpPressedThisFrame = _interact; } private void Update() { Vector2 mouseScreenPos = Mouse.current.position.ReadValue(); Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint( new Vector3(mouseScreenPos.x, mouseScreenPos.y, -Camera.main.transform.position.z) ); _airJumpDir = ((Vector2)mouseWorldPos - (Vector2)transform.position).normalized; _groundedCheckTimer += Time.deltaTime; _turnDelayTimer += Time.deltaTime; spriteRenderer.flipX = !_facingLeft; if (_springAnimator && _jumpPressedThisFrame) { _groundedCheckTimer = 0f; _springAnimator.SetTrigger(Spring); _springAnimator = null; _grounded = false; _fireSpring = true; _autoDrive = false; } if (_grounded && _jumpPressedThisFrame) { _grounded = false; _groundedCheckTimer = 0f; _jump = true; _jumpPressedThisFrame = false; } if (!_grounded && _airJumpCharges > 0 && _jumpPressedThisFrame) { Debug.Log(_airJumpDir); _airJump = true; } _jumpPressedThisFrame = false; } private void FixedUpdate() { if (_jump) { _jump = false; _grounded = false; _rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse); } if (_airJump) { _airJump = false; _airJumpCharges--; _rb.AddForce(_airJumpDir * airJumpForce, ForceMode2D.Impulse); } if (_fireSpring) { _fireSpring = false; _rb.linearVelocityX = 0; _rb.AddForce(Vector2.up * springPower, ForceMode2D.Impulse); } if (_autoDrive) { _rb.linearVelocityX = _facingLeft ? -runSpeed : runSpeed; } } private void OnTriggerEnter2D(Collider2D other) { if (other.gameObject.layer == LayerMask.NameToLayer("Spring")) _springAnimator = other.gameObject.GetComponent(); if (other.gameObject.layer == LayerMask.NameToLayer("Pickup")) { _airJumpCharges++; Destroy(other.gameObject); } } private void OnTriggerExit2D(Collider2D other) { if (other.gameObject.layer == LayerMask.NameToLayer("Spring")) { _springAnimator = null; } } private void OnCollisionEnter2D(Collision2D other) { CheckCollisions(other); } private void OnCollisionStay2D(Collision2D other) { CheckCollisions(other); } private void CheckCollisions(Collision2D other) { var contacts = new List(); other.GetContacts(contacts); if (_turnDelayTimer >= turnDelay && other.gameObject.layer != LayerMask.NameToLayer("Spring") && other.gameObject.layer != LayerMask.NameToLayer("Pickup")) { foreach (var c in contacts) { var x = c.normal.x; if (Mathf.Abs(x) > 0.1f) { _facingLeft = !_facingLeft; _turnDelayTimer = 0f; break; } } } _grounded = false; if (_groundedCheckTimer > turnDelay) { foreach (var c in contacts) { var y = c.normal.y; _grounded = Mathf.Approximately(1f, y); if (_grounded) { _autoDrive = true; return; } } } } } }