213 lines
6.8 KiB
C#
213 lines
6.8 KiB
C#
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
|
|
namespace AsteroidGame
|
|
{
|
|
public class CameraController : MonoBehaviour
|
|
{
|
|
private CameraControllActions _cameraActions;
|
|
private InputAction _movement;
|
|
private Transform _cameraTransform;
|
|
private Camera _cameraReference;
|
|
|
|
// Horizontal Movement
|
|
[SerializeField]
|
|
private float _maxSpeed = 5f;
|
|
private float _speed;
|
|
[SerializeField]
|
|
private float _acceleration = 10f;
|
|
[SerializeField]
|
|
private float _damping = 15f;
|
|
|
|
//Vertial Motion - Zooming
|
|
[SerializeField]
|
|
private float _stepSize = 2f;
|
|
[SerializeField]
|
|
private float _zoomDampening = 7.5f;
|
|
[SerializeField]
|
|
private float _minHeight = 5f;
|
|
[SerializeField]
|
|
private float _maxHeight = 50f;
|
|
[SerializeField]
|
|
private float _zoomSpeed = 2f;
|
|
|
|
//Rotation
|
|
[SerializeField]
|
|
private float _maxRotationSpeed = 1f;
|
|
|
|
//Screen Edge Motion
|
|
[SerializeField]
|
|
[Range(0f, 0.1f)]
|
|
private float _edgeTolerance = 0.05f;
|
|
[SerializeField]
|
|
private bool _useScreenEdge = false;
|
|
|
|
private Vector3 _targetPosition;
|
|
private float _zoomHeight;
|
|
private Vector3 _horizontalVelocity;
|
|
private Vector3 _lastPosition;
|
|
private Plane _cameraPlane;
|
|
|
|
Vector3 _startDrag;
|
|
|
|
private void Awake()
|
|
{
|
|
_cameraActions = new CameraControllActions();
|
|
|
|
_cameraReference = this.GetComponentInChildren<Camera>();
|
|
_cameraTransform = _cameraReference.transform;
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
_cameraPlane = new Plane(Vector3.up, Vector3.zero);
|
|
_zoomHeight = _cameraTransform.localPosition.y;
|
|
_cameraTransform.LookAt(this.transform);
|
|
_lastPosition = this.transform.position;
|
|
_movement = _cameraActions.Camera.Movement;
|
|
_cameraActions.Camera.RotateCamera.performed += RotateCamera;
|
|
_cameraActions.Camera.ZoomCamera.performed += ZoomCamera;
|
|
_cameraActions.Camera.Enable();
|
|
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
_cameraActions.Camera.RotateCamera.performed -= RotateCamera;
|
|
_cameraActions.Camera.ZoomCamera.performed -= ZoomCamera;
|
|
_cameraActions.Disable();
|
|
}
|
|
|
|
|
|
|
|
private void Update()
|
|
{
|
|
GetKeyboardMovement();
|
|
if (_useScreenEdge)
|
|
{
|
|
CheckMouseAtScreenEdge();
|
|
}
|
|
DragCamera();
|
|
UpdateVelocity();
|
|
UpdateCameraPosition();
|
|
UpdateBasePosition();
|
|
|
|
}
|
|
|
|
private void UpdateVelocity()
|
|
{
|
|
_horizontalVelocity = (this.transform.position - _lastPosition) / Time.deltaTime;
|
|
_horizontalVelocity.y = 0;
|
|
_lastPosition = this.transform.position;
|
|
}
|
|
|
|
private void GetKeyboardMovement()
|
|
{
|
|
Vector3 inputValue = _movement.ReadValue<Vector2>().x * GetCameraRight()
|
|
+ _movement.ReadValue<Vector2>().y * GetCameraForward();
|
|
inputValue = inputValue.normalized;
|
|
|
|
if (inputValue.sqrMagnitude > 0.1f)
|
|
{
|
|
_targetPosition += inputValue;
|
|
}
|
|
}
|
|
|
|
private Vector3 GetCameraRight()
|
|
{
|
|
Vector3 right = _cameraTransform.right;
|
|
right.y = 0;
|
|
return right;
|
|
}
|
|
|
|
private Vector3 GetCameraForward()
|
|
{
|
|
Vector3 forward = _cameraTransform.forward;
|
|
forward.y = 0;
|
|
return forward;
|
|
}
|
|
|
|
private void UpdateBasePosition()
|
|
{
|
|
if (_targetPosition.sqrMagnitude > 0.1f)
|
|
{
|
|
_speed = Mathf.Lerp(_speed, _maxSpeed, Time.deltaTime * _acceleration);
|
|
transform.position += _speed * Time.deltaTime * _targetPosition;
|
|
}
|
|
else
|
|
{
|
|
_horizontalVelocity = Vector3.Lerp(_horizontalVelocity, Vector3.zero, Time.deltaTime * _damping);
|
|
transform.position += _horizontalVelocity * Time.deltaTime;
|
|
}
|
|
|
|
_targetPosition = Vector3.zero;
|
|
}
|
|
|
|
private void RotateCamera(InputAction.CallbackContext inputValue)
|
|
{
|
|
if (!Mouse.current.middleButton.isPressed) { return; }
|
|
|
|
float value = inputValue.ReadValue<Vector2>().x;
|
|
transform.rotation = Quaternion.Euler(0f, value * _maxRotationSpeed + transform.rotation.eulerAngles.y, 0f);
|
|
}
|
|
|
|
private void ZoomCamera(InputAction.CallbackContext inputValue)
|
|
{
|
|
float value = -inputValue.ReadValue<Vector2>().y / 100f;
|
|
|
|
if (Mathf.Abs(value) > 0.1f)
|
|
{
|
|
_zoomHeight = _cameraTransform.localPosition.y + value * _stepSize;
|
|
if (_zoomHeight < _minHeight)
|
|
_zoomHeight = _minHeight;
|
|
else if (_zoomHeight > _maxHeight)
|
|
_zoomHeight = _maxHeight;
|
|
}
|
|
}
|
|
|
|
private void UpdateCameraPosition()
|
|
{
|
|
Vector3 zoomTarget = new Vector3(_cameraTransform.localPosition.x, _zoomHeight, _cameraTransform.localPosition.z);
|
|
zoomTarget -= _zoomSpeed * (_zoomHeight - _cameraTransform.localPosition.y) * Vector3.forward;
|
|
|
|
_cameraTransform.localPosition = Vector3.Lerp(_cameraTransform.localPosition, zoomTarget, Time.deltaTime * _zoomDampening);
|
|
_cameraTransform.LookAt(this.transform);
|
|
}
|
|
|
|
private void CheckMouseAtScreenEdge()
|
|
{
|
|
Vector2 mousePosition = Mouse.current.position.ReadValue();
|
|
Vector3 moveDirection = Vector3.zero;
|
|
|
|
if (mousePosition.x < _edgeTolerance * Screen.width)
|
|
moveDirection += -GetCameraRight();
|
|
else if (mousePosition.x > (1f - _edgeTolerance) * Screen.width)
|
|
moveDirection += GetCameraRight();
|
|
|
|
if (mousePosition.y < _edgeTolerance * Screen.height)
|
|
moveDirection += -GetCameraForward();
|
|
else if (mousePosition.y > (1f - _edgeTolerance) * Screen.height)
|
|
moveDirection += GetCameraForward();
|
|
|
|
_targetPosition += moveDirection;
|
|
}
|
|
|
|
private void DragCamera()
|
|
{
|
|
if (!Mouse.current.rightButton.isPressed) { return; }
|
|
|
|
|
|
Ray ray = _cameraReference.ScreenPointToRay(Mouse.current.position.ReadValue());
|
|
if (_cameraPlane.Raycast(ray,out float distance))
|
|
{
|
|
if (Mouse.current.rightButton.wasPressedThisFrame)
|
|
_startDrag = ray.GetPoint(distance);
|
|
else
|
|
_targetPosition += _startDrag - ray.GetPoint(distance);
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|