赞
踩
代码如下:
- 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 设置创建的物体在你想要的位置
注意 这的“0” 就是传入参数 0 代表第一位初始角色
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。