using Common.Abstracts; using Common.Events; using MessagePipe; using UnityEngine; using UnityEngine.InputSystem; namespace Player { public class PlayerController : AbstractMonoListener { private ISubscriber _screenResizeSubscriber; private InputAction _moveAction; private InputAction _sprintAction; private InputAction _scrollAction; private InputAction _lookAction; private InputAction _interactAction; private Vector2 _targetMovement; private Vector2 _currentMovement; private float _rotationAngle; private float _rotationVelocity; private Quaternion _targetRotation; private Camera _camera; private Vector3 _centerScreenPoint; private RaycastHit[] _landHit; private Vector3 _position; private Transform _follow; [SerializeField] private Vector2 heightLimits = new Vector2(0.5f, 40f); [SerializeField] private float currentHeight = 15f; [SerializeField] private float moveSpeed = 5f; [SerializeField] private float angle = 45f; private void Start() { _moveAction = InputSystem.actions.FindAction("Move"); _moveAction.performed += SetMovement; _moveAction.canceled += SetMovement; _camera = GetComponent(); _landHit = new RaycastHit[5]; _position = transform.position; _follow = new GameObject("Follow").transform; _follow.eulerAngles = new Vector3(angle, 0); CreateSubscriber(_screenResizeSubscriber, OnScreenResize); } private void Update() { Move(); } private void SetMovement(InputAction.CallbackContext callbackContext) { _targetMovement = callbackContext.ReadValue(); _currentMovement = Vector2.MoveTowards(_currentMovement, _targetMovement, Time.deltaTime); } private void Move() { var ray = _camera.ScreenPointToRay(_centerScreenPoint); var cnt = Physics.RaycastNonAlloc(ray, _landHit); if (cnt == 0) { return; } var pos = _landHit[0].point; for (int i = 0; i < cnt; i++) { if (_landHit[0].point.y > pos.y) { pos = _landHit[0].point; } } Vector3 forward = transform.forward; forward = new Vector3(forward.x, 0, forward.z).normalized; Vector3 right = Quaternion.Euler(0, 90, 0) * forward; Vector3 newPosition = transform.position + (_currentMovement.y * forward + _currentMovement.x * right) * moveSpeed; _position = Vector3.Lerp(_position, newPosition, Time.deltaTime); _position.y = Mathf.Lerp(_position.y, pos.y + currentHeight, Time.deltaTime); _follow.position = _position; } private void OnScreenResize(ScreenResizeEvent screenResizeEvent) { _centerScreenPoint = new Vector3(screenResizeEvent.width / 2, screenResizeEvent.height / 2); } } }