轮转图2D

原理

将3D轮转图的z轴转化成 2D轮转图的大小和层级关系 来实现轮转图的效果 。

工具:

DOTween

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

public class LZT2D : MonoBehaviour, IDragHandler, IEndDragHandler
{
    //需要实例化的预制体
    public GameObject prefab;
    //角度
    float angle;
    //数量
    public int num;
    //旋转需要改变的角度
    public float allang;
    //半径
    float r;
    //惯性速度
    float speed = 100;
    //线性插值的最大值
    float max = 1f;
    //线性插值的最小值
    float min = 0.5f;
    
    List<GameObject> lists = new List<GameObject>();
    List<GameObject> trans = new List<GameObject>();
    public List<Sprite> sprites = new List<Sprite>();

    // Start is called before the first frame update
    void Start()
    {
        //图片之间的间距
        //C=2*Π*r
        //计算半径:宽*数量/360+100(计算每一个图片占圆的大小 +100的间隔)
        r = prefab.GetComponent<RectTransform>().sizeDelta.x * num / (2 * Mathf.PI) + 100;
        //计算角度
        angle = 2 * Mathf.PI / num;
        OnMove();
    }

    private void OnMove()
    {
        for (int i = 0; i < num; i++)
        {
            if (lists.Count < num)
            {
                GameObject go = Instantiate(prefab, transform);
                go.name = i.ToString();
                go.GetComponent<Image>().sprite = sprites[i];
                lists.Add(go);
                trans.Add(go);
            }
            //计算x的位置(sin(角度)=对边/斜边)
            float x = Mathf.Sin(i * angle + allang) * r;
            //计算y的位置(con(角度)=临边/斜边)
            float z = Mathf.Cos(i * angle + allang) * r;
            lists[i].transform.localPosition = new Vector3(x, 0, 0);
             //计算大小  实现近大远小
            float scale = (z + r) / (2 * r) * (max - min) + min;
            lists[i].transform.localScale = Vector3.one * scale;
        }
        //根据大小 排序 
        trans.Sort((a, b) =>
        {
            if (a.transform.localScale.z > b.transform.localScale.z)
            {
                return 1;
            }
            else if (a.transform.localScale.z < b.transform.localScale.z)
            {
                return -1;
            }
            else
            {
                return 0;
            }
        });
        //根据排序设置层级
        for (int i = 0; i < trans.Count; i++)
        {
            trans[i].transform.SetSiblingIndex(i);
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        //eventData.delta.x 上一帧到这一帧的x轴距离
        //弧度/半径=角度
        allang += eventData.delta.x / r;
        OnMove();
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        //时间=距离/速度
        float time = Mathf.Abs(eventData.delta.x / speed);
        DOTween.To((a) =>
        {
            allang += a / r;
            OnMove();
        }, eventData.delta.x, 0, time).OnComplete(() =>
        {
            Allign(lists.IndexOf(trans[num - 1]));
        });
    }

    public void Allign(int n)
    {
        int temp = lists.IndexOf(trans[num - 1]);
        int zheng = temp - n;
        int fan = num - Math.Abs(zheng);
        fan = zheng < 0 ? fan : -fan;

        //正反转
        int interval = Mathf.Abs(zheng) < Mathf.Abs(fan) ? zheng : fan;
        float interAng = interval * angle;
        float moveAng = Mathf.Asin(trans[num - 1].transform.localPosition.x / r) + interAng;
        float time = Mathf.Abs(interAng * r / speed);

        DOTween.To((b) =>
        {
            allang = b;
            OnMove();
        }, allang, allang - moveAng, time).OnComplete(() =>
        {
            Debug.Log(n);
        });
    }
}

 

猜你喜欢

转载自blog.csdn.net/Steel_nails/article/details/132870800
2D
今日推荐