using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class Chart2d : MonoBehaviour, IDragHandler, IEndDragHandler
{
public Image prefab;
public int num; //数量
public float spacing; //间隔
private float c; //周长
private float r; //半径
private float ang; //均弧度
private float dis = 0; //拖动距离
private float max = 1; //最大缩放
private float min = 0.5f; //最小缩放
private float cutSpeed = 100; //速度削减
private List<GameObject> list = new List<GameObject>();
private List<Transform> sorts = new List<Transform>();
private void Start()
{
c = (prefab.rectTransform.rect.width + spacing) * num;
r = c / (2 * Mathf.PI);
ang = (2 * Mathf.PI) / num;
Move();
}
private void Move()
{
//移动弧度
var moveang = dis / r;
for (int i = 0; i < num; i++)
{
var x = Mathf.Sin(i * ang + moveang) * r;
var z = Mathf.Cos(i * ang + moveang) * r;
var p = (z + r) / (2 * r);//计算缩放比值
p = 1 - p;
var scale = (max - min) * p + min;
if (list.Count <= i)
{
GameObject img = Instantiate(prefab.gameObject, transform, false);
img.name = i.ToString();
list.Add(img);
sorts.Add(img.transform);
}
list[i].transform.localPosition = Vector3.right * x;//设置位置
list[i].transform.localScale = Vector3.one * scale;//设置缩放
}
//对图片缩放值进行排序
sorts.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 < sorts.Count; i++)
{
//设置显示层级位置
sorts[i].SetSiblingIndex(i);
}
}
public void OnDrag(PointerEventData eventData)
{
dis -= eventData.delta.x;
Move();
}
public void OnEndDrag(PointerEventData eventData)
{
var startspeed = eventData.delta.x;
var endspeed = 0;
var time = Mathf.Abs(startspeed) / cutSpeed;
DOTween.To((float a) =>
{
dis -= a;
Move();
}, startspeed, endspeed, time).OnComplete(() =>
{
//在集合中找 排序后集合的最后一个元素
Align(list.IndexOf(sorts[num - 1].gameObject));
});
}
public void Align(int n)
{
var i = list.IndexOf(sorts[num - 1].gameObject);
//判定物体旋转方向
var s = i - n;
var s2 = num - Mathf.Abs(s);
s2 = s > 0 ? -s2 : s2;
var s3 = Mathf.Abs(s) < Mathf.Abs(s2) ? s : s2;
//反三角函数计算需要移动过的距离
//(宽度/半径) + 需要经过的距离个数 * 每个旋转弧度
var moveang = Mathf.Asin(sorts[num - 1].localPosition.x / r) + s3 * ang;
var movedis = moveang * r;
var time = Mathf.Abs(movedis) / cutSpeed; // 剩余时间(需移动的距离 / 削减速度)
DOTween.To((float a) =>
{
dis = a;
Move();
}, dis, dis + movedis, time).OnComplete(() =>
{
//触发的脚本
//sorts[num-1].GetComponent<脚本>().方法();
});
}
}
2D轮转图
于 2023-01-29 14:20:32 首次发布