using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using Newtonsoft.Json;
using DG.Tweening;
using System.IO;
/// <summary>
/// 旋转图
/// </summary>
public class Rotart2D : MonoBehaviour,IDragHandler,IEndDragHandler
{
public Image prefab;//图片预制体
public float max = 1;//缩小最大值
public float min = 0.5f;//缩小最小值
public int n ;//物体个数
public string path = "";
public float space = 100;//UI间距的单位是像素
public float cut = 10;//减速度
float zc;//周长
float r;//半径
float ang;//弧度
List<Image> list = new List<Image>();
List<Transform> sl = new List<Transform>();
float moveang = 0;//拖到弧度
public GameObject h;
void Start()
{
//周长=(人物宽度+间距)*个数
zc = (prefab.rectTransform.rect.width + space) * n;
//半径=周长/
r = zc / (2 * Mathf.PI);
//弧度= /个数
ang = 2 * Mathf.PI / n;
Move();
}
public void Move()
{
for (int i = 0; i < n; i++)
{
//判断集合中有就不创建,没有在创建
if (list.Count <= i)
{
list.Add(Instantiate(prefab, transform));
list[i].transform.GetComponent<Image>().sprite = Resources.Load<Sprite>("Image/"+ path + i);
list[i].name = path + i;
sl.Add(list[i].transform);
}
float x = Mathf.Sin(i * ang + moveang) * r;
float y = Mathf.Cos(i * ang + moveang) * r;
//计算y 0到1的比值 跟雷达图计算ux坐标相同
float p = (y + r) / (2 * r);
//先行差值公式
float scale = (max - min) * p + min;
list[i].rectTransform.anchoredPosition = new Vector2(x, 0);
list[i].transform.localScale = Vector3.one * scale;
}
sl.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 < sl.Count; i++)
{
sl[i].SetSiblingIndex(i);
}
}
public void OnDrag(PointerEventData eventData)
{
//每帧拖动距离
float dis = eventData.delta.x;
//通过距离计算弧度
float dragAng = dis / r;
moveang += dragAng;
Move();
}
public void OnEndDrag(PointerEventData eventData)
{
float speed = eventData.delta.x;
float time = Mathf.Abs(speed) / cut;
DOTween.To((a) =>
{
//通过距离计算弧度
float drang = a / r;
moveang += drang;
Move();
}, speed, 0, time).OnComplete(() =>
{
Aling(list.IndexOf(sl[n - 1].GetComponent<Image>()));
});
}
public void Aling(int id)
{
//当前下标
int index = list.IndexOf(sl[n - 1].GetComponent<Image>());
//指定下标与当前下标的间隔
int sp = id - index;
//计算另一个旋转方向需要的间隔
int sp0 = n - Mathf.Abs(sp);
//顺、逆时针 一正一反
sp0 = sp > 0 ? -sp0 : sp0;
//选择两个方向中间隔较小一方旋转
int end = Mathf.Abs(sp) < Mathf.Abs(sp0) ? sp : sp0;
//计算间隔弧度
float spAng = end * ang;
//需要旋转的弧度=与中间偏差的弧度+间隔的弧度
float AlingAng = Mathf.Asin(sl[n - 1].GetComponent<RectTransform>().anchoredPosition.x / r) + spAng;
//通过需要旋转的弧度计算需要旋转的距离
float Alingdis = AlingAng * r;
//通过需要旋转的距离计算旋转时间
float time = Mathf.Abs(Alingdis) / cut;
DOTween.To((a) =>
{
moveang = a;
Move();
}, moveang, moveang - AlingAng, time);
}
}
![]()