using System.Diagnostics;
using UnityEngine.XR.Interaction.Toolkit.Inputs.Readers;
using UnityEngine.XR.Interaction.Toolkit.Interactors;
namespace UnityEngine.XR.Interaction.Toolkit.AR.Inputs
{
///
/// Component that provides the twist rotation or two finger drag value from a touchscreen for mobile AR.
/// Intended to be used with an as its object reference
/// to provide a rotation value.
///
///
///
[AddComponentMenu("XR/Input/Screen Space Rotate Input", 11)]
[HelpURL(XRHelpURLConstants.k_ScreenSpaceRotateInput)]
public class ScreenSpaceRotateInput : MonoBehaviour, IXRInputValueReader
{
[SerializeField]
[Tooltip("The ray interactor to get the attach transform from.")]
XRRayInteractor m_RayInteractor;
///
/// The ray interactor to get the attach transform from.
///
public XRRayInteractor rayInteractor
{
get => m_RayInteractor;
set => m_RayInteractor = value;
}
[SerializeField]
[Tooltip("The input used to read the twist delta rotation value.")]
XRInputValueReader m_TwistDeltaRotationInput = new XRInputValueReader("Twist Delta Rotation");
///
/// Input to use for the screen twist delta relative to the previous frame.
///
///
public XRInputValueReader twistDeltaRotationInput
{
get => m_TwistDeltaRotationInput;
set => XRInputReaderUtility.SetInputProperty(ref m_TwistDeltaRotationInput, value, this);
}
[SerializeField]
[Tooltip("The input used to read the drag delta value.")]
XRInputValueReader m_DragDeltaInput = new XRInputValueReader("Drag Delta");
///
/// Input to use for the screen drag delta relative to the previous frame.
///
///
public XRInputValueReader dragDeltaInput
{
get => m_DragDeltaInput;
set => XRInputReaderUtility.SetInputProperty(ref m_DragDeltaInput, value, this);
}
[SerializeField]
[Tooltip("The input used to read the screen touch count value.")]
XRInputValueReader m_ScreenTouchCountInput = new XRInputValueReader("Screen Touch Count");
///
/// The input used to read the screen touch count value.
///
///
public XRInputValueReader screenTouchCountInput
{
get => m_ScreenTouchCountInput;
set => XRInputReaderUtility.SetInputProperty(ref m_ScreenTouchCountInput, value, this);
}
///
/// See .
///
[Conditional("UNITY_EDITOR")]
protected void Reset()
{
#if UNITY_EDITOR
m_RayInteractor = GetComponentInParent(true);
#endif
}
///
/// See .
///
protected void Awake()
{
if (m_RayInteractor == null)
m_RayInteractor = GetComponentInParent(true);
}
///
/// See .
///
protected void OnEnable()
{
m_TwistDeltaRotationInput.EnableDirectActionIfModeUsed();
m_DragDeltaInput.EnableDirectActionIfModeUsed();
m_ScreenTouchCountInput.EnableDirectActionIfModeUsed();
}
///
/// See .
///
protected void OnDisable()
{
m_TwistDeltaRotationInput.DisableDirectActionIfModeUsed();
m_DragDeltaInput.DisableDirectActionIfModeUsed();
m_ScreenTouchCountInput.DisableDirectActionIfModeUsed();
}
///
public Vector2 ReadValue()
{
TryReadValue(out var value);
return value;
}
///
public bool TryReadValue(out Vector2 value)
{
if (m_TwistDeltaRotationInput.TryReadValue(out var twistDeltaRotation))
{
value = new Vector2(-twistDeltaRotation, 0f);
return true;
}
if (m_ScreenTouchCountInput.ReadValue() > 1 &&
m_DragDeltaInput.TryReadValue(out var dragDeltaRotation))
{
var attachTransform = m_RayInteractor.attachTransform;
var worldToVerticalOrientedDevice = Quaternion.Inverse(Quaternion.LookRotation(attachTransform.forward, Vector3.up));
var rotatedDelta = worldToVerticalOrientedDevice * attachTransform.rotation * dragDeltaRotation;
value = new Vector2((rotatedDelta.x / Screen.dpi) * -50f, 0f);
return true;
}
value = Vector2.zero;
return false;
}
}
}