1,制作显示形象的预制体,两层image,美观一些
2,制作一个image,就是效果里面的半透明灰色背景,在这里挂脚本
代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using DG.Tweening;
public class RotationChart2D : MonoBehaviour,IDragHandler, IEndDragHandler
{
public Image prefab; //预制体
public float max=1; //缩放最大值
public float min=0.5f; //缩放最小值
public int n; //个数
public float spacing = 100;//UI间距单位是像素 比较大
public float cut = 100; //减速度
float c;
float r;
float ang;
List<Image> list = new List<Image>();
List<Transform> sortList = new List<Transform>();
//拖动弧度
float moveAng = 0;
//角色
private GameObject player;
//雷达显示部分
public GameObject show;
void Start()
{
//周长=(宽+间距)*个数
c = (prefab.rectTransform.rect.width + spacing) * n;
//半径=周长/2π
r = c / (2 * Mathf.PI);
ang = 2 * Mathf.PI / n;
//转动方法
Move();
//获取数据
show.GetComponent<RadarMap3>().GetArr();
}
public void Move()
{
for (int i = 0; i < n; i++)
{
//判断集合中有就不创建,没有再创建
if(list.Count<=i)
{
list.Add(Instantiate(prefab, transform));//添加图片
list[i].transform.GetChild(0).GetComponent<Image>().sprite = Resources.Load<Sprite>("Image/image" + i);
sortList.Add(list[i].transform);
}
float x = Mathf.Sin(i * ang+moveAng) * r;
float z = Mathf.Cos(i * ang+moveAng) * r;
//通过z 计算 近大远小
//计算z 0-1的比值 和雷达图计算uv坐标相同
float p = (z + r) / (2 * r);
float scale = (max - min) * p + min; //这是一个比值
//float scale = min * (1 - p) + max * p;
list[i].rectTransform.anchoredPosition = new Vector2(x, 0);
list[i].transform.localScale = Vector3.one * scale;
}
//排序
sortList.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 < sortList.Count; i++)
{
sortList[i].SetSiblingIndex(i);
}
}
// Update is called once per frame
void Update()
{
}
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 dragAng = a / r;
moveAng += dragAng;
//结束拖拽也会移动
Move();
},speed,0,time).OnComplete(()=>
{
//下标 获取图片的id
Align(list.IndexOf(sortList[n - 1].GetComponent<Image>()));
});
}
//对齐
public void Align(int id)
{
//当前下标
int index = list.IndexOf(sortList[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;
//弧度=asin(对边x/斜边r)
//需要旋转的弧度=与中间偏差的弧度+间隔弧度
float AlignAng = Mathf.Asin(sortList[n - 1].GetComponent<RectTransform>().anchoredPosition.x / r)+spAng;
//距离=弧度*半径
float AlugnDis = AlignAng * r;
//时间
float time = Mathf.Abs(AlugnDis)/cut;
//自动对齐
DOTween.To((a)=>
{
moveAng = a;
Move();
},moveAng,moveAng-AlignAng,time).OnComplete(()=> //生成角色
{
if (player != null)
{
Destroy(player);
}
player = Instantiate(Resources.Load<GameObject>("Player/" + id));
player.transform.position = new Vector3(0.45f, -2, 0);
player.transform.eulerAngles = new Vector3(0, 180, 0);
show.GetComponent<RadarMap3>().Change(id);
});
}
}
参考参数:
这里的Show是雷达图,可以显示每个人的数据,我们下期再讲雷达图。
补充:SetSiblingIndex 设置创建的物体在你想要的位置
3. 若是点击button 转到初始第一位
注意 这的“0” 就是传入参数 0 代表第一位初始角色