Files
DeltaVR/Assets/_PROJECT/Components/NewHandPresence/Prefabs/XROrigin Scripts/AbstractSlider.cs

113 lines
3.5 KiB
C#

using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
abstract public class AbstractSlider : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public RectTransform sliderBackground; // Assign in Inspector
public float minValue = 0f;
public float maxValue = 1f;
public float slideareaOffsetMultiplier = 0.9f;
public float CurrentValue { get; private set; }
public float CurrentNormalizedValue { get; private set; }
private RectTransform handleRect;
private Vector2 backgroundStart;
private float backgroundWidth;
public System.Action<float, bool> OnValueChanged;
private void OnEnable()
{
if (null == handleRect)
{
handleRect = GetComponent<RectTransform>();
}
if (sliderBackground != null)
{
backgroundStart = sliderBackground.position;
backgroundWidth = sliderBackground.rect.width;
}
UpdateHandlePosition();
}
virtual public void OnBeginDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
virtual public void OnDrag(PointerEventData eventData)
{
UpdateSlider(eventData);
}
virtual public void OnEndDrag(PointerEventData eventData)
{
UpdateSlider(eventData, true);
EventSystem.current.SetSelectedGameObject(null);
}
virtual public void SetHandleValue(float unnormalizedValue)
{
SetValuesFromValue(unnormalizedValue);
UpdateHandlePosition();
}
virtual public void SetHandleNormalizedValue(float normalizedValue)
{
SetValuesFromNormalizedValue(normalizedValue);
UpdateHandlePosition();
}
virtual protected void UpdateHandlePosition()
{
if (null == handleRect) return; // The options menu might not be opened yet
float halfWidth = sliderBackground.rect.width * 0.5f;
float limit = halfWidth * slideareaOffsetMultiplier;
float x = Mathf.Lerp(-limit, limit, CurrentNormalizedValue);
handleRect.localPosition = new Vector3(x, handleRect.localPosition.y, 0);
}
virtual protected void UpdateSlider(PointerEventData eventData, bool draggingEnded = false)
{
Vector2 localPoint;
RectTransformUtility.ScreenPointToLocalPointInRectangle(sliderBackground, eventData.position, eventData.pressEventCamera, out localPoint);
float halfWidth = sliderBackground.rect.width * 0.5f;
// Only allow dragging within 90% of the slider width, centered
float limit = halfWidth * slideareaOffsetMultiplier;
float clampedX = Mathf.Clamp(localPoint.x, -limit, limit);
Vector3 newPosition = new Vector3(clampedX, handleRect.localPosition.y, handleRect.localPosition.z);
handleRect.localPosition = newPosition;
// Normalize within the limited 90% range
float normalized = (clampedX + limit) / (limit * 2f);
SetValuesFromValue(Mathf.Lerp(minValue, maxValue, normalized));
OnValueChanged?.Invoke(CurrentValue, draggingEnded);
}
protected void SetValuesFromNormalizedValue(float normalizedValue)
{
CurrentNormalizedValue = normalizedValue;
CurrentValue = CurrentNormalizedValue * (maxValue - minValue) + minValue;
}
protected void SetValuesFromValue(float unnormalizedValue)
{
CurrentValue = unnormalizedValue;
CurrentNormalizedValue = (CurrentValue - minValue) / (maxValue - minValue);
}
}