2D轮转图

using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class Chart2d : MonoBehaviour, IDragHandler, IEndDragHandler
{    
    public Image prefab;
    public int num; //数量
    public float spacing; //间隔

    private float c; //周长
    private float r; //半径
    private float ang; //均弧度
    private float dis = 0; //拖动距离
    private float max = 1; //最大缩放
    private float min = 0.5f; //最小缩放
    private float cutSpeed = 100; //速度削减

    private List<GameObject> list = new List<GameObject>();
    private List<Transform> sorts = new List<Transform>();

    private void Start()
    {
        c = (prefab.rectTransform.rect.width + spacing) * num;
        r = c / (2 * Mathf.PI);
        ang = (2 * Mathf.PI) / num; 
        Move();
    }

    private void Move()
    {
        //移动弧度
        var moveang = dis / r;

        for (int i = 0; i < num; i++)
        {
            var x = Mathf.Sin(i * ang + moveang) * r;
            var z = Mathf.Cos(i * ang + moveang) * r;
            var p = (z + r) / (2 * r);//计算缩放比值
            p = 1 - p;
            var scale = (max - min) * p + min;
            if (list.Count <= i)
            {
                GameObject img = Instantiate(prefab.gameObject, transform, false);
                img.name = i.ToString();
                list.Add(img);
                sorts.Add(img.transform);
            }

            list[i].transform.localPosition = Vector3.right * x;//设置位置
            list[i].transform.localScale = Vector3.one * scale;//设置缩放
        }

        //对图片缩放值进行排序
        sorts.Sort((a, b) =>
        {
            if (a.localScale.x < b.localScale.x)
            {
                return -1;
            }
            else if (a.localScale.x == b.localScale.x)
            {
                return 0;
            }
            else
            {
                return 1;
            }
        });
        for (int i = 0; i < sorts.Count; i++)
        {
            //设置显示层级位置
            sorts[i].SetSiblingIndex(i);
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        dis -= eventData.delta.x;
        Move();
    }


    public void OnEndDrag(PointerEventData eventData)
    {
        var startspeed = eventData.delta.x;
        var endspeed = 0;
        var time = Mathf.Abs(startspeed) / cutSpeed;
        DOTween.To((float a) =>
        {
            dis -= a;
            Move();
        }, startspeed, endspeed, time).OnComplete(() =>
        {
            //在集合中找 排序后集合的最后一个元素
            Align(list.IndexOf(sorts[num - 1].gameObject));
        });
    }

    public void Align(int n)
    {
        var i = list.IndexOf(sorts[num - 1].gameObject);
        //判定物体旋转方向
        var s = i - n;
        var s2 = num - Mathf.Abs(s);
        s2 = s > 0 ? -s2 : s2;
        var s3 = Mathf.Abs(s) < Mathf.Abs(s2) ? s : s2;

        //反三角函数计算需要移动过的距离    
        //(宽度/半径) + 需要经过的距离个数 * 每个旋转弧度
        var moveang = Mathf.Asin(sorts[num - 1].localPosition.x / r) + s3 * ang;
        var movedis = moveang * r;
        var time = Mathf.Abs(movedis) / cutSpeed; // 剩余时间(需移动的距离 / 削减速度)
        DOTween.To((float a) =>
        {
            dis = a;
            Move();
        }, dis, dis + movedis, time).OnComplete(() =>
        {
            //触发的脚本
            //sorts[num-1].GetComponent<脚本>().方法();
        });
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值