游戏中雷达图,轮转图基础模型

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项 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值