unity 圆形滑动条slider 弧形滑动条效果及代码分析

13 篇文章 0 订阅

因为大多数滑动条slider都是水平或者垂直那种直的,在一些项目上缺少美感

所以这里做一种比较好看的圆形滑动条  (或者说是circle slider 弧形滑动条)

可以在一个弧面上滑动,看起来更加有科技感

在此提供下思路,抛砖引玉



圆形样式,最简单的一种,因为可以调节成360度的,属于基本样式


或者是双侧弧形,根据圆形的改造


弧形样式,其实就是把圆形的约束在一定范围内,但效果很不错

简单添加了缓动效果,下面提供参考代码和预置体下载


不多说直接上弧形的代码

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

public class ArcSlider : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
{
    public Image handleButton;
    float circleRadius = 0.0f;

    bool isPointerDown = false;
    public Image baseCircle;

    //忽略圈内的交互
    public float ignoreInTouchRadiusHandleOffset = 10;

    Vector3 handleButtonLocation;

    [Tooltip("初始角度到终止角度")]
    public float firstAngle = 30;
    public float secondAngle = 150;

    float tempAngle = 30;//用来缓动
    public void Start()
    {
        circleRadius = Mathf.Sqrt(Mathf.Pow(handleButton.GetComponent<RectTransform>().localPosition.x, 2) + Mathf.Pow(handleButton.GetComponent<RectTransform>().localPosition.y, 2));
        ignoreInTouchRadiusHandleOffset = circleRadius - ignoreInTouchRadiusHandleOffset;

        handleButtonLocation = handleButton.GetComponent<RectTransform>().localPosition;
    }
    public void Update()
    {
        //用来重置
        if (Input.GetKeyDown(KeyCode.R))
        {
            ReSet();
        }
    }
    public void ReSet()
    {
        handleButton.GetComponent<RectTransform>().localPosition = handleButtonLocation;
    }
	public void OnPointerEnter( PointerEventData eventData )
	{
		StartCoroutine( "TrackPointer" );
	}
	
	//如果需要移动到外部时仍然有效可以去掉这里的
	public void OnPointerExit( PointerEventData eventData )
	{
		StopCoroutine( "TrackPointer" );
	}

	public void OnPointerDown(PointerEventData eventData)
	{
		isPointerDown= true;
	}

	public void OnPointerUp(PointerEventData eventData)
	{
		isPointerDown= false;
	}
    
	IEnumerator TrackPointer()
	{
		var ray = GetComponentInParent<GraphicRaycaster>();
		var input = FindObjectOfType<StandaloneInputModule>();

		var text = GetComponentInChildren<Text>();
		
		if( ray != null && input != null )
		{
			while( Application.isPlaying )
			{                    
				//这个是左侧的
				if (isPointerDown)
				{
					Vector2 localPos;
                    //获取鼠标当前位置out里赋值
					RectTransformUtility.ScreenPointToLocalPointInRectangle( transform as RectTransform, Input.mousePosition, ray.eventCamera, out localPos );

                    localPos.x = -localPos.x;

                    //半径
                    float mouseRadius = Mathf.Sqrt(localPos.x*localPos.x+localPos.y*localPos.y);

                    //阻止圆内部点击的响应,只允许在一个圆环上进行响应
                    if (mouseRadius > ignoreInTouchRadiusHandleOffset)// && handleButton.GetComponent<RectTransform>().localPosition.x <= 0
                    {
                        //0-180  -180-0偏移后的角度 从第一象限校正到0-360
                        float angle = (Mathf.Atan2(localPos.y, localPos.x)) * Mathf.Rad2Deg;
                        if (angle < 0) angle = 360 + angle;;

                        if (angle < firstAngle) angle = firstAngle;
                        if (angle > secondAngle) angle = secondAngle;

                        angle = (tempAngle + angle) / 2f;
                        tempAngle = angle;
                        //改变小圆的位置
                        handleButton.GetComponent<RectTransform>().localPosition = new Vector3(Mathf.Cos(-angle / Mathf.Rad2Deg + 45.0f * Mathf.PI) * circleRadius, Mathf.Sin(-angle / Mathf.Rad2Deg + 45.0f * Mathf.PI) * circleRadius, 0);


                        this.transform.parent.GetComponent<Image>().color = Color.Lerp(Color.green, Color.blue, (angle - firstAngle) / (secondAngle - firstAngle));

                            
                        //数值的偏移值
                        float temp = secondAngle - firstAngle;// 360 - 285 + 64;

                        float tempangle = (angle - firstAngle)/ (secondAngle - firstAngle);
                            
                        //可能会出现很小的数 注意保留小数位数
                        text.text = tempangle.ToString();
                    }
                }
				yield return 0;
			}        
		}   
	}
}

需要建立一个button,然后把代码拖到radialSliderImage上面,然后该拖什么拖什么


主要思路就是使用Atan2转换鼠标点击位置到圆心的角度

匹配鼠标滑动位置和显示绘制

圆形的按钮实际上也只是简单跟随鼠标而已

一切都是建立在简单圆形公式上面的

麻烦的地方主要在凑数字而已


最后放上下载地址

http://download.csdn.net/detail/shenmifangke/9708871

注意需要把预置体ArcSlider放到自己建立的canvas上使用




  • 5
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
Unity圆形滑动是一种用户界面的控件,它可以以圆的形式展示并允许用户通过拖动滑块来选择一个值。它通常被用在需要用户进行选项选择或数值调整的场景中。 Unity圆形滑动的基本原理是将一个圆形滑动控件与数值范围关联起来。用户可以通过点击并拖动滑块来选择一个特定的数值,滑块的位置与数值的关联通常以圆心为起点从0到360度的方式来表示。当用户拖动滑块时,可以通过监测滑块的角度或者位置的改变来获取用户的选值,并根据选值进行相应的操作。 实现Unity圆形滑动主要可以通过以下步骤: 1.创建一个圆形的背景作为滑动的底部,可以使用Unity的UI系统或者自定义绘制技术来实现。 2.在底部圆形背景上创建一个滑块,滑块的形状可以是一个小圆点或者其他你想要的形状。 3.实现用户拖动滑块的交互,可以通过监测鼠标或手指的位置变化来判断滑块的移动,并根据滑块的位置计算数值的选择。 4.根据滑块的位置或角度计算数值,可以通过线性映射或者其他的数值转换方法来将滑块的位置映射为一个数值范围内的数值。 5.根据滑块的数值进行相应的操作,例如更新游戏的属性、调整音量或其他与数值相关的操作。 总而言之,Unity圆形滑动是一种实现用户交互和数值选择的控件,通过拖动滑块来选择数值,并根据数值进行相应的操作。可以根据需求进行自定义设计和实现。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值