Stratasys-450mc-VR/Assets/Scripts/Interactions/XRSlider.cs

139 lines
3.9 KiB
C#

using System;
using UnityEngine.Events;
using UnityEngine.XR.Interaction.Toolkit;
namespace UnityEngine.XR.Content.Interaction
{
/// <summary>
/// An interactable that follows the position of the interactor on a single axis
/// </summary>
public class XRSlider : XRBaseInteractable
{
[Serializable]
public class ValueChangeEvent : UnityEvent<float> { }
[SerializeField]
[Tooltip("The object that is visually grabbed and manipulated")]
Transform m_Handle = null;
[SerializeField]
[Tooltip("The value of the slider")]
[Range(0.0f, 1.0f)]
float m_Value = 0.5f;
[SerializeField]
[Tooltip("The offset of the slider at value '1'")]
float m_MaxPosition = 0.5f;
[SerializeField]
[Tooltip("The offset of the slider at value '0'")]
float m_MinPosition = -0.5f;
[SerializeField]
[Tooltip("Events to trigger when the slider is moved")]
ValueChangeEvent m_OnValueChange = new ValueChangeEvent();
IXRSelectInteractor m_Interactor;
/// <summary>
/// The value of the slider
/// </summary>
public float value
{
get => m_Value;
set
{
SetValue(value);
SetSliderPosition(value);
}
}
/// <summary>
/// Events to trigger when the slider is moved
/// </summary>
public ValueChangeEvent onValueChange => m_OnValueChange;
void Start()
{
SetValue(m_Value);
SetSliderPosition(m_Value);
}
protected override void OnEnable()
{
base.OnEnable();
selectEntered.AddListener(StartGrab);
selectExited.AddListener(EndGrab);
}
protected override void OnDisable()
{
selectEntered.RemoveListener(StartGrab);
selectExited.RemoveListener(EndGrab);
base.OnDisable();
}
void StartGrab(SelectEnterEventArgs args)
{
m_Interactor = args.interactorObject;
UpdateSliderPosition();
}
void EndGrab(SelectExitEventArgs args)
{
m_Interactor = null;
}
public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
{
base.ProcessInteractable(updatePhase);
if (updatePhase == XRInteractionUpdateOrder.UpdatePhase.Dynamic)
{
if (isSelected)
{
UpdateSliderPosition();
}
}
}
void UpdateSliderPosition()
{
// Put anchor position into slider space
var localPosition = transform.InverseTransformPoint(m_Interactor.GetAttachTransform(this).position);
var sliderValue = Mathf.Clamp01((localPosition.z - m_MinPosition) / (m_MaxPosition - m_MinPosition));
SetValue(sliderValue);
SetSliderPosition(sliderValue);
}
void SetSliderPosition(float value)
{
if (m_Handle == null)
return;
var handlePos = m_Handle.localPosition;
handlePos.z = Mathf.Lerp(m_MinPosition, m_MaxPosition, value);
m_Handle.localPosition = handlePos;
}
void SetValue(float value)
{
m_Value = value;
m_OnValueChange.Invoke(m_Value);
}
void OnDrawGizmosSelected()
{
var sliderMinPoint = transform.TransformPoint(new Vector3(0.0f, 0.0f, m_MinPosition));
var sliderMaxPoint = transform.TransformPoint(new Vector3(0.0f, 0.0f, m_MaxPosition));
Gizmos.color = Color.green;
Gizmos.DrawLine(sliderMinPoint, sliderMaxPoint);
}
void OnValidate()
{
SetSliderPosition(m_Value);
}
}
}