1.雷达图:
示例:以五边形为例
1.首先创建UI--Image,然后吧Image中的"Image"组件删掉,替换成我们写的雷达组件
2.代码部分:
3.雷达效果:
2.轮转图3D:
1.我是创建一个空物体.挂载此脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class Rolling : MonoBehaviour
{
// Start is called before the first frame update
public GameObject prefab;//随便来个预制体
public int num;//预制体数量
float angle;//角度
float allangle;//改变的角度
public float radius;//半径
public List<GameObject> list = new List<GameObject>();
public List<Transform> tra = new List<Transform>();
void Start()
{
angle = 2 * Mathf.PI / num;
OnMove();
}
void OnMove()
{
//生成预制体
for (int i = 0; i < num; i++)
{
if (list.Count < num)
{
GameObject go = Instantiate(prefab, transform);
list.Add(go);
go.GetComponent<RollingItem>().roll = this;
tra.Add(go.transform);
}
//给预制体初始化位置
float x = Mathf.Sin(i * angle + allangle) * radius;
float z = Mathf.Cos(i * angle + allangle) * radius;
list[i].transform.localPosition = new Vector3(x, 0, z);
}
}
//item项调用此方法
public void Drag(float dis)
{
allangle -= dis / radius;
OnMove();
}
//item项调用此方法
public void Interia(float dis)
{
//用了dotween插件,dis为初始值,a为变化值,0是终值,2是时间,后面是完成之后的回调
DOTween.To(() => dis, (a) =>
{
Drag(a);
}, 0, 2).OnComplete(() =>
{
//排序,找到距离相机最近的item,超出或者不够给对齐
tra.Sort((a, b) => { return (int)(a.position.z - b.position.z); });
float moveangle = Mathf.Asin(tra[0].localPosition.x / radius);
DOTween.To(() => allangle, (t) => { allangle = t; OnMove(); }, allangle + moveangle, 2);
});
}
}
2.预制体上的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RollingItem : MonoBehaviour
{
public Rolling roll;
private void OnMouseUp()//抬起时,调用惯性
{
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 vec = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
Input.mousePosition.y, pos.z));
float dis = vec.x - transform.position.x;
roll.Interia(dis);
}
private void OnMouseDrag()//拖拽,旋转
{
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
Vector3 vec = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,
Input.mousePosition.y, pos.z));
float dis = vec.x - transform.position.x;
roll.Drag(dis);
}
}
3.初始位置摆放的效果
3.轮转图2D:
1.既然是2D,肯定要放到Canvas上了
2.还是与3D差不多
3.代码部分
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using DG.Tweening;
public class Rotationchart2D : MonoBehaviour, IDragHandler, IEndDragHandler
{
public GameObject prefab;
public int num;
public float r;
//移动弧度
public float moveAngle;
float angle;
//差值
public float max = 1;
public float min = 0.5f;
//间距 (单位是像素)
public float padding = 50;
//减速度
public float cutSpeed = 50;
List<GameObject> list = new List<GameObject>();
List<Transform> trans = new List<Transform>();
// Start is called before the first frame update
void Start()
{
angle = 2 * Mathf.PI / num;
//算出合适的生成半径
r = (prefab.GetComponent<RectTransform>().sizeDelta.x + padding) * num / (2 * Mathf.PI);
OnMove();
}
public void OnMove()
{
for (int i = 0; i < num; i++)
{
float x = Mathf.Sin(angle * i + moveAngle) * r;
float z = Mathf.Cos(angle * i + moveAngle) * r;
if (list.Count < num)
{
GameObject go = Instantiate(prefab, transform);
go.name = i.ToString();
list.Add(go);
trans.Add(go.transform);
}
list[i].transform.localPosition = new Vector3(x, 0, 0);
//跟据 z值(距离摄像机前后) / 直径 来求出比例 * 差值 + min 最小值不能小于min限制 求出缩放比
float scale = (z + r) / (2 * r) * (max - min) + min;//实现ui近大远小
list[i].transform.localScale = Vector3.one * scale;
}
//根据图片缩放排序更改层级
trans.Sort((a, b) => { return (int)(a.transform.localScale.z * 100 - b.transform.localScale.z * 100); });
for (int j = 0; j < trans.Count; j++)
{
trans[j].transform.SetSiblingIndex(j);
}
}
public void OnDrag(PointerEventData eventData)
{
float dis = eventData.delta.x;
//需要转动的弧度数
float angle = dis / r;
//3D和2D的区别
//3D时 z越小离摄像机越近 因为相机放在了-10的位置上 所以-=
//2D时 z越大离摄像机越近 所以+=
moveAngle += angle;
OnMove();
}
/// <summary>
/// 惯性向前 并对齐
/// </summary>
/// <param name="eventData"></param>
public void OnEndDrag(PointerEventData eventData)
{
// eventData.delta.x会有负值
// 惯性时间
float moveTime = Mathf.Abs(eventData.delta.x / cutSpeed);
DOTween.To((a) =>
{
//调用drag方法
float angel = a / r;
moveAngle += angel;
OnMove();
}, eventData.delta.x, 0, moveTime).OnComplete(() =>
{
//当前z值最大的 离摄像机最近 自动对齐
Align(list.IndexOf(trans[num - 1].gameObject));
});
}
/// <summary>
/// 对齐方法
/// </summary>
/// <param name="n"></param>
public void Align(int n)
{
int index = list.IndexOf(trans[num - 1].gameObject);
int zheng = n - index;
int fan = num - Mathf.Abs(zheng);
fan = zheng < 0 ? fan : -fan;
int insert = Mathf.Abs(zheng) < Mathf.Abs(fan) ? zheng : fan;
float insertAngle = insert * angle;
//得到弧长
float alignAngel = Mathf.Asin(trans[num - 1].localPosition.x / r) + insertAngle;
float moveTime = Mathf.Abs(alignAngel * r / cutSpeed);
DOTween.To((a) =>
{
moveAngle = a;
OnMove();
}, moveAngle, moveAngle - alignAngel, 2);
}
}
4.效果:
tip:这个2d写的是拖得是父对象,不是每个item项