Skip to content

Instantly share code, notes, and snippets.

@MarGamaDev
Created October 6, 2023 08:55
Show Gist options
  • Save MarGamaDev/3bd4be30836c41950cb5c72e1134084c to your computer and use it in GitHub Desktop.
Save MarGamaDev/3bd4be30836c41950cb5c72e1134084c to your computer and use it in GitHub Desktop.
using MyBox;
using System.Collections;
using System.Linq;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem;
public partial class ShuffleController : MonoBehaviour
{
[Header("Input References")]
private PlayerInput _input;
[SerializeField] private InputActionReference _clickReference, _rightClickReference, _pointReference, _mouseDeltaReference, _zoomDeltaReference, _escapeReference;
[Space]
[SerializeField] private Camera _shuffleCam;
[SerializeField] private Transform _camXPivot; // the pivot point that moves along the x axis
[SerializeField] private Transform _camYPivot; // the pivot point that moves along the y axis
[SerializeField] private Transform _camZoomPivot; // the pivot point that moves towards and away from the turning pivots
[SerializeField] private LayerMask _UiMask;
[Header("Rotation Settings")]
[SerializeField] private float _rotateSpeedInAnglePerSecond = 1;
[SerializeField] private float2 _rotateSensitivity = new float2(1, 1);
[SerializeField] private float _upperLookClamp = 80, _lowerLookClamp = 40; // maximum and minimum angle for the the x axis
[SerializeField] private float _minZoomDistance = 10, _maxZoomDistance = 30; // the minimum and maximum distance the camera can be from the center
[SerializeField] private float _zoomSpeed = 1;
public float2 RotSens { get { return _rotateSensitivity; } set { _rotateSensitivity = value; } }
private float3 _mousePosition => _shuffleCam.ScreenToViewportPoint(_pointReference.action.ReadValue<Vector2>()); // the position of the mouse in viewport coords
private float2 _mouseDelta => _mouseDeltaReference.action.ReadValue<Vector2>(); // the displacement of the mouse since last frame
private bool _isRightClicking => _rightClickReference.action.IsPressed();
private bool _isClicking => _clickReference.action.IsPressed();
private float2 _zoomDelta => _zoomDeltaReference.action.ReadValue<Vector2>();
private IShuffleUiSelectable _hoverSelected;
private void Start()
{
_input = PlayerManager.Instance.PlayerInputManager;
}
private void Update()
{
UpdateHoverSelected();
if (_isRightClicking)
RotateCamera();
else if (_isClicking)
OnClick();
if (_zoomDelta.y != 0)
AdjustZoom(Mathf.Sign(_zoomDelta.y));
}
private void OnEnable()
{
GridManager.Current?.LockPhysicsObjects();
MouseManager.AddUnlockingObject(this);
_input.actions[_escapeReference.action.name].performed += ExitShuffle;
}
private void OnDisable()
{
GridManager.Current?.UnlockPhysicsObjects();
_input.actions[_escapeReference.action.name].performed -= ExitShuffle;
}
private void OnClick()
{
// don't allow clicking when rotating camera
if (_isRightClicking)
return;
// send ray forward from where you click
Ray ray = _shuffleCam.ViewportPointToRay(_mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, _UiMask))
{
// if it's a selectable, fire it's event
if (EventSystem.current.IsPointerOverGameObject())
return;
IShuffleUiSelectable selectable;
if (hitInfo.transform.TryGetComponent<IShuffleUiSelectable>(out selectable))
{
selectable.SelectComponent();
}
}
}
private void UpdateHoverSelected()
{
if (_hoverSelected != null)
{
_hoverSelected.HoverOver(false);
}
Ray ray = _shuffleCam.ViewportPointToRay(_mousePosition);
RaycastHit hitInfo;
if (Physics.Raycast(ray, out hitInfo, Mathf.Infinity, _UiMask) && !EventSystem.current.IsPointerOverGameObject())
{
IShuffleUiSelectable selectable;
if (hitInfo.transform.TryGetComponent<IShuffleUiSelectable>(out selectable))
{
if (selectable != _hoverSelected)
_hoverSelected = selectable;
_hoverSelected.HoverOver(true);
}
return;
}
_hoverSelected = null;
}
/// <summary>
/// Rotates the camera along the x axis, then along the x axis.
/// The rotation along the y axis is clamped.
/// </summary>
private void RotateCamera()
{
// calculate the rotations we want to apply
float xRotation = _mouseDelta.y * (_rotateSpeedInAnglePerSecond * Time.deltaTime) * _rotateSensitivity.x;
float yRotation = _mouseDelta.x * (_rotateSpeedInAnglePerSecond * Time.deltaTime) * _rotateSensitivity.y;
// rotate and clamp the x rotation
float currentRotation = _camXPivot.localEulerAngles.x;
currentRotation -= xRotation;
currentRotation = math.clamp(currentRotation, _lowerLookClamp, _upperLookClamp);
// apply x rotation and then the y rotation
_camXPivot.localEulerAngles = Vector3.right * currentRotation;
_camYPivot.Rotate(Vector3.up, yRotation);
}
/// <summary>
/// Changes the size of the orthographic camera to simulate zooming in and out
/// </summary>
/// <param name="direction"> 1 to move it closer, -1 to move it farther away </param>
private void AdjustZoom(float direction)
{
float newSize = _shuffleCam.orthographicSize - direction * _zoomSpeed;
newSize = math.clamp(newSize, _minZoomDistance, _maxZoomDistance);
_shuffleCam.orthographicSize = newSize;
}
private void ExitShuffle(InputAction.CallbackContext context)
{
FindObjectOfType<ShuffleTransition>().TransitionToController();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment