113 lines
3.5 KiB
C#
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);
|
|
}
|
|
|
|
}
|