#region Copyright RenGuiYou. All rights reserved. //===================================================== // NeatlyFrameWork // Author: RenGuiyou // Feedback: mailto:750539605@qq.com //===================================================== #endregion using System; using UnityEngine; using UnityEngine.EventSystems; namespace Neatly.UI { public class NSlider : EmptyRaycast, IDragHandler, IPointerDownHandler, IPointerUpHandler { private float m_TweenTime = 0.5f; public enum Direction { LeftToRight, RightToLeft, } [SerializeField] private Direction m_Direction = Direction.LeftToRight; [SerializeField] private RectTransform m_FillRect; [SerializeField] private bool m_HasBar; [SerializeField] private float m_StartBorder; [SerializeField] private float m_EndBorder; private float m_Width; private float Width { get { if (m_Width == 0) { m_Width = rectTransform.GetSizeDeltaX(); } return m_Width; } } public Direction direction { get { return m_Direction; } set { if (!SetPropertyUtility.SetStruct(ref m_Direction, value)) return; UpdateVisuals(); } } public RectTransform fillRect { get { return m_FillRect; } set { m_FillRect = value; } } [Range(0, 1)] [SerializeField] protected float m_Value; public float value { get { return GetValue(); } } private Action m_OnValueChanged; private Action m_OnPointerDown; private Action m_OnPointerUp; protected override void Start() { base.Start(); raycastTarget = m_HasBar; } public void AddOnValueChangedListener(Action action) { m_OnValueChanged = action; } public void AddPointerListener(Action pointerDown, Action PointerUp) { m_OnPointerDown = pointerDown; m_OnPointerUp = PointerUp; } public void SetValue(float val) { if (val > 1) { val = 1; } else if (val < 0) { val = 0; } if (Math.Abs(m_Value - val) < float.Epsilon) { return; } m_Value = val; UpdateVisuals(); } public void SetTweenTime(float time) { m_TweenTime = time; } public void TweenValue(float val) { UITween.SliderMove(this, val, m_TweenTime); } public float GetValue() { return m_Value; } #if UNITY_EDITOR protected override void OnValidate() { UpdateVisuals(); } #endif private void UpdateVisuals() { UpdateFillRect(); } private void UpdateFillRect() { if (!m_FillRect) return; float val = m_Value; switch (m_Direction) { case Direction.LeftToRight: m_FillRect.anchorMin = Vector2.zero; m_FillRect.anchorMax = new Vector2(val, 1); break; case Direction.RightToLeft: m_FillRect.anchorMin = new Vector2(1 - val, 0); m_FillRect.anchorMax = Vector2.one; break; } } public void OnPointerDown(PointerEventData eventData) { m_OnPointerDown?.Invoke(); UpdateDrag(eventData); } public void OnPointerUp(PointerEventData eventData) { m_OnPointerUp?.Invoke(); } public void OnDrag(PointerEventData eventData) { UpdateDrag(eventData); } void UpdateDrag(PointerEventData eventData) { if (!m_HasBar) return; Vector2 localCursor; if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, eventData.position, eventData.pressEventCamera, out localCursor)) return; float val = 0; float curWidth = Width; if (m_HasBar) { curWidth = Width - m_StartBorder - m_EndBorder; } switch (m_Direction) { case Direction.LeftToRight: val = (localCursor.x + curWidth / 2) / curWidth; break; case Direction.RightToLeft: val = (curWidth / 2 - localCursor.x) / curWidth; break; } val = Mathf.Clamp01(val); if (m_HasBar) { val = ((Width - m_StartBorder - m_EndBorder)* val + m_StartBorder) / Width; } SetValue(val); if (m_OnValueChanged != null) { m_OnValueChanged(val); } } } }