using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; namespace Cryville.Crtr.Config { public abstract class PVPNumberBase : PropertyValuePanel { [SerializeField] EventTrigger m_ctn; [SerializeField] RectTransform m_handleArea; [SerializeField] Image m_handle; [SerializeField] Text m_text; #pragma warning disable IDE0051 protected void Start() { var ev = new EventTrigger.Entry { eventID = EventTriggerType.InitializePotentialDrag }; ev.callback.AddListener(e => OnInitializePotentialDrag((PointerEventData)e)); m_ctn.triggers.Add(ev); ev = new EventTrigger.Entry { eventID = EventTriggerType.Drag }; ev.callback.AddListener(e => OnDrag((PointerEventData)e)); m_ctn.triggers.Add(ev); ev = new EventTrigger.Entry { eventID = EventTriggerType.EndDrag }; ev.callback.AddListener(e => OnEndDrag((PointerEventData)e)); m_ctn.triggers.Add(ev); ev = new EventTrigger.Entry { eventID = EventTriggerType.PointerClick }; ev.callback.AddListener(e => OnPointerClick((PointerEventData)e)); m_ctn.triggers.Add(ev); OnIdle(); } protected override void OnValueUpdated() { m_text.text = MappedValue.ToString(); } protected virtual void OnIdle() { } void Update() { if (use) { SetRatio(GetRatioFromPos(pp)); SetValueFromPos(pp); } } void OnRectTransformDimensionsChange() { m_handleArea.sizeDelta = new Vector2(m_handle.rectTransform.rect.height - m_handle.rectTransform.rect.width, 0); } #pragma warning restore IDE0051 Camera cam; Vector2 pp; bool use, nouse; public void OnInitializePotentialDrag(PointerEventData eventData) { eventData.useDragThreshold = false; pp = eventData.position; } public void OnDrag(PointerEventData eventData) { if (nouse) return; cam = eventData.pressEventCamera; if (!use) { var delta = eventData.position - pp; float dx = Mathf.Abs(delta.x), dy = Mathf.Abs(delta.y); if (dx > dy) use = true; else if (dx < dy) nouse = true; } if (use) { pp = eventData.position; eventData.Use(); } } public void OnEndDrag(PointerEventData eventData) { if (!nouse) { SetValueFromPos(eventData.position); OnIdle(); eventData.Use(); use = false; } nouse = false; } public void OnPointerClick(PointerEventData eventData) { SetValueFromPos(eventData.position); eventData.Use(); } float GetRatioFromPos(Vector2 pos) { Vector2 lp; if (RectTransformUtility.ScreenPointToLocalPointInRectangle(m_handleArea, pos, cam, out lp)) { lp -= m_handleArea.rect.position; return Mathf.Clamp01(lp.x / m_handleArea.rect.width); } return float.NegativeInfinity; } void SetValueFromPos(Vector2 pos) { double min = double.NegativeInfinity, max = double.PositiveInfinity; if (Range != null && Range.Length == 2) { min = (double)Range[0]; max = (double)Range[1]; } double ratio = GetRatioFromPos(pos); double result = GetValue(ratio, Time.deltaTime, min, max); if (result < min) result = min; else if (result > max) result = max; RawValue = result; } protected abstract double GetValue(double ratio, float deltaTime, double min, double max); protected void SetRatio(float ratio) { m_handle.rectTransform.anchorMin = new Vector2(ratio, m_handle.rectTransform.anchorMin.y); m_handle.rectTransform.anchorMax = new Vector2(ratio, m_handle.rectTransform.anchorMax.y); m_handle.rectTransform.anchoredPosition = Vector2.zero; } } }