using UnityEngine;
using UnityEngine.EventSystems;
namespace CnControls
{
public class Touchpad : MonoBehaviour, IDragHandler, IPointerUpHandler, IPointerDownHandler
{
///
/// Current event camera reference. Needed for the sake of Unity Remote input
///
public Camera CurrentEventCamera { get; set; }
///
/// The name of the horizontal axis for this touchpad to update
///
public string HorizontalAxisName = "Horizontal";
///
/// The name of the vertical axis for this touchpad to update
///
public string VerticalAxisName = "Vertical";
///
/// Whether this touchpad should preserve inertia when the finger is lifted
///
public bool PreserveInertia = true;
///
/// The speed of decay of inertia
///
public float Friction = 3f;
private VirtualAxis _horizintalAxis;
private VirtualAxis _verticalAxis;
private int _lastDragFrameNumber;
private bool _isCurrentlyTweaking;
///
/// Joystick movement direction
/// Specifies the axis along which it can move
///
[Tooltip("Constraints on the joystick movement axis")]
public ControlMovementDirection ControlMoveAxis = ControlMovementDirection.Both;
private void OnEnable()
{
// When we enable, we get our virtual axis
_horizintalAxis = _horizintalAxis ?? new VirtualAxis(HorizontalAxisName);
_verticalAxis = _verticalAxis ?? new VirtualAxis(VerticalAxisName);
// And register them in our input system
CnInputManager.RegisterVirtualAxis(_horizintalAxis);
CnInputManager.RegisterVirtualAxis(_verticalAxis);
}
private void OnDisable()
{
// When we disable, we just unregister our axis
// It also happens before the game object is Destroyed
CnInputManager.UnregisterVirtualAxis(_horizintalAxis);
CnInputManager.UnregisterVirtualAxis(_verticalAxis);
}
public virtual void OnDrag(PointerEventData eventData)
{
// Some bitwise logic for constraining the touchpad along one of the axis
// If the "Both" option was selected, non of these two checks will yield "true"
if ((ControlMoveAxis & ControlMovementDirection.Horizontal) != 0)
{
_horizintalAxis.Value = eventData.delta.x;
}
if ((ControlMoveAxis & ControlMovementDirection.Vertical) != 0)
{
_verticalAxis.Value = eventData.delta.y;
}
_lastDragFrameNumber = Time.renderedFrameCount;
}
public void OnPointerUp(PointerEventData eventData)
{
_isCurrentlyTweaking = false;
if (!PreserveInertia)
{
_horizintalAxis.Value = 0f;
_verticalAxis.Value = 0f;
}
}
public void OnPointerDown(PointerEventData eventData)
{
_isCurrentlyTweaking = true;
OnDrag(eventData);
}
private void Update()
{
if (_isCurrentlyTweaking && _lastDragFrameNumber < Time.renderedFrameCount - 2)
{
_horizintalAxis.Value = 0f;
_verticalAxis.Value = 0f;
}
if (PreserveInertia && !_isCurrentlyTweaking)
{
_horizintalAxis.Value = Mathf.Lerp(_horizintalAxis.Value, 0f, Friction * Time.deltaTime);
_verticalAxis.Value = Mathf.Lerp(_verticalAxis.Value, 0f, Friction * Time.deltaTime);
}
}
}
}