cultivation/Assets/Scripts/Player/PlayerController.cs

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);
}
}
}