2D轮转图

在空物体上挂载下面脚本 ,其中的对齐方法OnAlign可以看做一个对外开放的接口

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

public class RC2D : MonoBehaviour,IDragHandler,IEndDragHandler
{
    //图片预制体
    public GameObject m_Prefab;
    //图片个数
    public int m_Num;
    //图片间距
    public float m_Spacing;
    //半径
    float m_R;
    //每个图片之间的弧度
    float m_Rad;
    //移动弧度
    float m_MoveRad=0;
    //存储图片游戏对象
    List<GameObject> m_List=new List<GameObject>();
    //存储图片transform信息
    List<Transform> m_Trans=new List<Transform>();
    private void Start()
    {
        m_Rad = 2 * Mathf.PI / m_Num;
        m_R = (m_Prefab.GetComponent<RectTransform>().sizeDelta.x+m_Spacing)*m_Num/(2*Mathf.PI);//算出合适的半径
        OnMove();//初始化图片游戏对象
    }

    private void OnMove()
    {
       for (int i = 0; i < m_Num; i++)
        {
            float x=Mathf.Sin(i*m_Rad+m_MoveRad)*m_R;
            float z=Mathf.Cos(i*m_Rad+m_MoveRad)*m_R;
            if (m_List.Count<=i)
            {
                GameObject go = Instantiate(m_Prefab, transform);
                go.GetComponent<Image>().sprite=Resources.Load<Sprite>(i.ToString());
                go.name=i.ToString();
                m_List.Add(go);
                m_Trans.Add(go.transform);
            }
            m_List[i].transform.localPosition = new Vector3(x, 0, 0);
            float scale = (z + m_R) / (2 * m_R) * 0.5f + 0.5f;//根据z值求出缩放比
            m_List[i].transform.localScale=Vector3.one*scale;//缩放赋值
        }
        //根据图片缩放排序更改层级
        m_Trans.Sort((a, b) =>
        {
            return (int)(a.localScale.z*10-b.localScale.z*10);
        });
        for (int i = 0;i < m_Trans.Count;i++)
        {
            m_Trans[i].SetSiblingIndex(i);
        }
    }
    /// <summary>
    /// 结束拖拽
    /// </summary>
    /// <param name="eventData"></param>
    public void OnEndDrag(PointerEventData eventData)
    {
        //惯性
        DOTween.To((a) =>
        {
            m_MoveRad += (a/m_R);
            OnMove();
        }, eventData.delta.x, 0, 2).OnComplete(() =>
        {
            //惯性结束,对齐
            OnAlign(m_List.IndexOf(m_Trans[m_Num - 1].gameObject));
        });
    }
    /// <summary>
    /// 对齐
    /// </summary>
    /// <param name="v"></param>
    public void OnAlign(int v)
    {
        int index = m_List.IndexOf(m_Trans[m_Num - 1].gameObject);

        //计算旋转最短路径
        int posi = v - index;//2D中不能写成index-v,否则指定查找效果错误
        int nega = m_Num - Mathf.Abs(posi);
        nega = posi < 0 ? nega : -nega;
        int insert = Mathf.Abs(posi) < Mathf.Abs(nega) ? posi : nega;

        //忽略最短路径
        //int insert = v-index;//2D中不能写成index-v,否则指定查找效果错误
        float totalRad = Mathf.Asin(m_Trans[m_Num - 1].localPosition.x / m_R) + insert * m_Rad;
        DOTween.To((a) =>
        {
            m_MoveRad = a;
            OnMove();
        },m_MoveRad,m_MoveRad-totalRad,1);
    }
    /// <summary>
    /// 拖拽中
    /// </summary>
    /// <param name="eventData"></param>
    public void OnDrag(PointerEventData eventData)
    {
        //3D轮转图与2D轮转图的区别
        //3D时 z越小离摄像机越近 因为相机放在了-10的位置上  所以-=
        //2D时 z越大离摄像机越近 所以+=
        m_MoveRad += (eventData.delta.x / m_R);
        OnMove();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值