2D轮转图的实现

首先创建一个背景图和预制体

接下来就是通过挂在BG上的脚本实现轮转图的效果:

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

public class Rotationchart2D : MonoBehaviour, IDragHandler, IEndDragHandler
{
    public GameObject prefab;
    //图片数量
    public int num;
    //半径
    float r;
    //差值
    float max = 1;
    float min = 0.5f;
    //间距 (单位是像素)
    float padding = 50;
    //移动弧度
    float moveAngle = 0;
    float angle;
    //减速度
    float cutSpeed = 50;
    List<GameObject> list = new List<GameObject>();
    List<Transform> trans = new List<Transform>();

    // Start is called before the first frame update
    void Start()
    {
        angle = 2 * Mathf.PI / num;
        //算出合适的生成半径
        r = (prefab.GetComponent<RectTransform>().sizeDelta.x + padding) * num / (2 * Mathf.PI);
        OnMove();
    }
    public void OnMove()
    {
        for (int i = 0; i < num; i++)
        {
            float x = Mathf.Sin(angle * i + moveAngle) * r;
            float z = Mathf.Cos(angle * i + moveAngle) * r;
            if (list.Count < num)
            {
                GameObject go = Instantiate(prefab, transform);
                go.name = i.ToString();
                list.Add(go);
                trans.Add(go.transform);
            }
            list[i].transform.localPosition = new Vector3(x, 0, 0);
            //跟据  z值(距离摄像机前后) / 直径 来求出比例  *  差值  + min 最小值不能小于min限制   求出缩放比
            float scale = (z + r) / (2 * r) * (max - min) + min;
            list[i].transform.localScale = Vector3.one * scale;
        }
        //根据图片缩放排序更改层级
        trans.Sort((a, b) => { return (int)(a.transform.localScale.z * 100 - b.transform.localScale.z * 100); });
        for (int j = 0; j < trans.Count; j++)
        {
            trans[j].transform.SetSiblingIndex(j);
        }
    }

    public void OnDrag(PointerEventData eventData)
    {
        float dis = eventData.delta.x;
        //需要转动的弧度数
        float angle = dis / r;
        //3D和2D的区别
        //3D时 z越小离摄像机越近 因为相机放在了-10的位置上  所以-=
        //2D时 z越大离摄像机越近 所以+=
        moveAngle += angle;
        OnMove();
    }
    /// <summary>
    /// 惯性向前  并对齐
    /// </summary>
    /// <param name="eventData"></param>
    public void OnEndDrag(PointerEventData eventData)
    {
        // eventData.delta.x会有负值
        // 惯性时间
        float moveTime = Mathf.Abs(eventData.delta.x / cutSpeed);
        DOTween.To((a) =>
        {
            //调用drag方法
            float angel = a / r;
            moveAngle += angel;
            OnMove();
        }, eventData.delta.x, 0, moveTime).OnComplete(() =>
        {
            //当前z值最大的  离摄像机最近  自动对齐
            Align(list.IndexOf(trans[num - 1].gameObject));
        });
    }
    /// <summary>
    /// 对齐方法
    /// </summary>
    /// <param name="n"></param>
    public void Align(int n)
    {
        int index = list.IndexOf(trans[num - 1].gameObject);
        int zheng = n - index; 
        int fan = num - Mathf.Abs(zheng);
        fan = zheng < 0 ? fan : -fan;
        int insert = Mathf.Abs(zheng) < Mathf.Abs(fan) ? zheng : fan;
        float insertAngle = insert * angle;
        //得到弧长
        float alignAngel = Mathf.Asin(trans[num - 1].localPosition.x / r) + insertAngle;
        float moveTime = Mathf.Abs(alignAngel * r / cutSpeed);
        DOTween.To((a) =>
        {
            moveAngle = a;
            OnMove();
        }, moveAngle, moveAngle - alignAngel, 2);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值