自定义实现UISlider

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Sprites;
using UnityEngine.EventSystems;

namespace UnityEngine.UIExtend
{
    [AddComponentMenu("UI/UISlider", 15)]
    public class UISlider : Graphic, IDragHandler, IEndDragHandler
    {
        public Slider.Direction m_Direction;
        public System.Action<float> m_OnValueChanged;
        [SerializeField]
        Sprite m_BackGround;
        [SerializeField]
        Sprite m_Fill;
        public RectTransform m_Handle;

        [Range(0, 1)]
        public float value;
        public Color fg_Color;
        private float curValue;
        public override void SetNativeSize()
        {
            base.SetNativeSize();
        }
        public override Texture mainTexture
        {
            get
            {
                if (m_BackGround == null)
                {
                    if (material != null && material.mainTexture != null)
                    {
                        return material.mainTexture;
                    }
                    return s_WhiteTexture;
                }

                return m_BackGround.texture;
            }
        }
        protected UISlider()
        {
            useLegacyMeshGeneration = false;
            raycastTarget = false;
            curValue = value;
        }

        protected override void OnPopulateMesh(VertexHelper vh)
        {
            base.OnPopulateMesh(vh);
            vh.Clear();
            Texture tex = mainTexture;
            var r = GetPixelAdjustedRect();
            Vector4 v = new Vector4(r.x, r.y, r.width + r.x, r.height + r.y);
            float horizontalNormal = r.width * value;
            float verticalNormal = r.height * value;
            if (curValue != value)
            {
                m_OnValueChanged?.Invoke(value);
                curValue = value;
            }
            if (m_Direction == Slider.Direction.LeftToRight || m_Direction == Slider.Direction.RightToLeft)
            {
                if (m_Direction == Slider.Direction.LeftToRight)
                {
                    if (m_BackGround != null)
                    {
                        var bgUV = DataUtility.GetInnerUV(m_BackGround);
                        var color32 = color;
                        float fill = (bgUV.z - bgUV.x) * value;
                        vh.AddVert(new Vector3(v.x + horizontalNormal, v.y), color32, new Vector2(bgUV.x + fill, bgUV.y)); //0
                        vh.AddVert(new Vector3(v.x + horizontalNormal, v.w), color32, new Vector2(bgUV.x + fill, bgUV.w)); //1
                        vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(bgUV.z, bgUV.w)); //2
                        vh.AddVert(new Vector3(v.z, v.y), color32, new Vector2(bgUV.z, bgUV.y)); //3
                        vh.AddTriangle(0, 1, 2);
                        vh.AddTriangle(2, 3, 0);
                    }
                    if (m_Fill != null)
                    {
                        var fileSpUV = DataUtility.GetInnerUV(m_Fill);
                        var colort = fg_Color;
                        float fill = (fileSpUV.z - fileSpUV.x) * value;
                        vh.AddVert(new Vector3(v.x, v.y), colort, new Vector2(fileSpUV.x, fileSpUV.y));  //4
                        vh.AddVert(new Vector3(v.x, v.w), colort, new Vector2(fileSpUV.x, fileSpUV.w)); //5
                        vh.AddVert(new Vector3(v.x + horizontalNormal, v.w), colort, new Vector2(fileSpUV.x + fill, fileSpUV.w)); //6
                        vh.AddVert(new Vector3(v.x + horizontalNormal, v.y), colort, new Vector2(fileSpUV.x + fill, fileSpUV.y)); //7
                        vh.AddTriangle(4, 5, 6);
                        vh.AddTriangle(6, 7, 4);
                    }
                    if (m_Handle != null)
                    {
                        float diffValue=r.width*(0.5f-m_Handle.anchorMin.x) - m_Handle.rect.width*(0.5f-m_Handle.anchorMin.x);
                        m_Handle.anchoredPosition = new Vector2(v.x + horizontalNormal+diffValue, m_Handle.anchoredPosition.y);
                    }
                }
                if (m_Direction == Slider.Direction.RightToLeft)
                {
                    if (m_BackGround != null)
                    {

                        var spriteUV = DataUtility.GetInnerUV(m_BackGround);
                        var color32 = color;
                        float fill = (spriteUV.z - spriteUV.x) * value;
                        vh.AddVert(new Vector3(v.x, v.y), color32, new Vector2(spriteUV.x, spriteUV.y));
                        vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(spriteUV.x, spriteUV.w));
                        vh.AddVert(new Vector3(v.z - horizontalNormal, v.w), color32, new Vector2(spriteUV.z - fill, spriteUV.w));
                        vh.AddVert(new Vector3(v.z - horizontalNormal, v.y), color32, new Vector2(spriteUV.z - fill, spriteUV.y));
                        vh.AddTriangle(4, 5, 6);
                        vh.AddTriangle(6, 7, 4);
                    }
                    if (m_Fill != null)
                    {
                        var fileSpUV = DataUtility.GetInnerUV(m_Fill);
                        var colort = fg_Color;
                        float fill = (fileSpUV.z - fileSpUV.x) * value;
                        float vertFill = r.width * value;
                        vh.AddVert(new Vector3(v.z - horizontalNormal, v.y), colort, new Vector2(fileSpUV.z - fill, fileSpUV.y));
                        vh.AddVert(new Vector3(v.z - horizontalNormal, v.w), colort, new Vector2(fileSpUV.z - fill, fileSpUV.w));
                        vh.AddVert(new Vector3(v.z, v.w), colort, new Vector2(fileSpUV.z, fileSpUV.w));
                        vh.AddVert(new Vector3(v.z, v.y), colort, new Vector2(fileSpUV.z, fileSpUV.y));
                        vh.AddTriangle(0, 1, 2);
                        vh.AddTriangle(2, 3, 0);
                    }
                    if (m_Handle != null)
                    {
                        float diffValue=r.width*(0.5f-m_Handle.anchorMin.x) - m_Handle.rect.width*(0.5f-m_Handle.anchorMin.x);
                        m_Handle.anchoredPosition = new Vector2(v.z - horizontalNormal + diffValue, m_Handle.anchoredPosition.y);
                    }
                }
            }
            else
            {
                if (m_Direction == Slider.Direction.BottomToTop)
                {
                    if (m_BackGround != null)
                    {

                        var spriteUV = DataUtility.GetInnerUV(m_BackGround);
                        var color32 = color;
                        float fill = (spriteUV.w - spriteUV.y) * value;

                        vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(spriteUV.x, spriteUV.w)); //0
                        vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(spriteUV.z, spriteUV.w)); //1
                        vh.AddVert(new Vector3(v.z, v.y + verticalNormal), color32, new Vector2(spriteUV.z, spriteUV.y + fill)); //2
                        vh.AddVert(new Vector3(v.x, v.y + verticalNormal), color32, new Vector2(spriteUV.x, spriteUV.y + fill)); //3

                        vh.AddTriangle(0, 1, 2);
                        vh.AddTriangle(2, 3, 0);
                    }
                    if (m_Fill != null)
                    {
                        var fileSpUV = DataUtility.GetInnerUV(m_Fill);
                        var colort = fg_Color;
                        float fill = (fileSpUV.w - fileSpUV.y) * value;

                        vh.AddVert(new Vector3(v.x, v.y + verticalNormal), colort, new Vector2(fileSpUV.x, fileSpUV.y + fill));
                        vh.AddVert(new Vector3(v.z, v.y + verticalNormal), colort, new Vector2(fileSpUV.z, fileSpUV.y + fill));
                        vh.AddVert(new Vector3(v.z, v.y), colort, new Vector2(fileSpUV.z, fileSpUV.y));
                        vh.AddVert(new Vector3(v.x, v.y), colort, new Vector2(fileSpUV.x, fileSpUV.y));

                        vh.AddTriangle(4, 5, 6);
                        vh.AddTriangle(6, 7, 4);
                    }
                    if (m_Handle != null)
                    {
                        float diffValue=r.height*(0.5f-m_Handle.anchorMin.y) - m_Handle.rect.height*(0.5f-m_Handle.anchorMin.y);
                        m_Handle.anchoredPosition = new Vector2(m_Handle.anchoredPosition.x, v.y + verticalNormal+diffValue);
                    }
                       
                }
                if (m_Direction == Slider.Direction.TopToBottom)
                {
                    if (m_Fill != null)
                    {
                        var spriteUV = DataUtility.GetInnerUV(m_Fill);
                        var color32 = color;
                        float fill = (spriteUV.w - spriteUV.y) * value;
                        vh.AddVert(new Vector3(v.x, v.w), color32, new Vector2(spriteUV.x, spriteUV.w)); //0
                        vh.AddVert(new Vector3(v.z, v.w), color32, new Vector2(spriteUV.z, spriteUV.w)); //1
                        vh.AddVert(new Vector3(v.z, v.w - verticalNormal), color32, new Vector2(spriteUV.z, spriteUV.w - fill)); //2
                        vh.AddVert(new Vector3(v.x, v.w - verticalNormal), color32, new Vector2(spriteUV.x, spriteUV.w - fill)); //3

                        vh.AddTriangle(0, 1, 2);
                        vh.AddTriangle(2, 3, 0);
                    }
                    if (m_BackGround != null)
                    {
                        var fileSpUV = DataUtility.GetInnerUV(m_BackGround);
                        var colort = fg_Color;
                        float fill = (fileSpUV.w - fileSpUV.y) * value;
                        vh.AddVert(new Vector3(v.x, v.w - verticalNormal), colort, new Vector2(fileSpUV.x, fileSpUV.w - fill));
                        vh.AddVert(new Vector3(v.z, v.w - verticalNormal), colort, new Vector2(fileSpUV.z, fileSpUV.w - fill));
                        vh.AddVert(new Vector3(v.z, v.y), colort, new Vector2(fileSpUV.z, fileSpUV.y));
                        vh.AddVert(new Vector3(v.x, v.y), colort, new Vector2(fileSpUV.x, fileSpUV.y));

                        vh.AddTriangle(4, 5, 6);
                        vh.AddTriangle(6, 7, 4);
                    }
                    if (m_Handle != null)
                    {
                        float diffValue=r.height*(0.5f-m_Handle.anchorMin.y) - m_Handle.rect.height*(0.5f-m_Handle.anchorMin.y);
                        m_Handle.anchoredPosition = new Vector2(m_Handle.anchoredPosition.x, v.w - verticalNormal+diffValue);
                    }
                }
            }



        }

        public void OnDrag(PointerEventData eventData)
        {
            if (m_Handle == null) return;
            Vector2 localCursor;
            if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(this.rectTransform, eventData.position, eventData.pressEventCamera, out localCursor))
                return;
            var r = GetPixelAdjustedRect();
            if (m_Direction == Slider.Direction.LeftToRight)
                value = Mathf.Clamp01((localCursor.x - r.x) / r.width);
            else if (m_Direction == Slider.Direction.RightToLeft)
                value = 1 - Mathf.Clamp01((localCursor.x - r.x) / r.width);
            else if (m_Direction == Slider.Direction.TopToBottom)
                value = 1 - Mathf.Clamp01((localCursor.y - r.y) / r.height);
            else if (m_Direction == Slider.Direction.BottomToTop)
                value = Mathf.Clamp01((localCursor.y - r.y) / r.height);
            SetVerticesDirty();
        }

        public void OnEndDrag(PointerEventData eventData)
        {
            if (m_Handle == null) return;
            Vector2 localCursor;
            if (!RectTransformUtility.ScreenPointToLocalPointInRectangle(this.rectTransform, eventData.position, eventData.pressEventCamera, out localCursor))
                return;
            var r = GetPixelAdjustedRect();
            if (m_Direction == Slider.Direction.LeftToRight)
                value = Mathf.Clamp01((localCursor.x - r.x) / r.width);
            else if (m_Direction == Slider.Direction.RightToLeft)
                value = 1 - Mathf.Clamp01((localCursor.x - r.x) / r.width);
            else if (m_Direction == Slider.Direction.TopToBottom)
                value = 1 - Mathf.Clamp01((localCursor.y - r.y) / r.height);
            else if (m_Direction == Slider.Direction.BottomToTop)
                value = Mathf.Clamp01((localCursor.y - r.y) / r.height);
            SetVerticesDirty();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值