forked from cgvr/DeltaVR
		
	
		
			
				
	
	
		
			140 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			140 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);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 |