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); } }
