116 lines
3.2 KiB
C#
116 lines
3.2 KiB
C#
using Common.Abstracts;
|
|
using Common.Events;
|
|
using MessagePipe;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
namespace Player
|
|
{
|
|
public class PlayerController : AbstractMonoListener
|
|
{
|
|
private ISubscriber<ScreenResizeEvent> _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<Camera>();
|
|
_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<Vector2>();
|
|
_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);
|
|
}
|
|
}
|
|
} |