简易3D轮转图

旋转前:

旋转后:

 

3D旋转效果代码部分:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 3D轮转图
/// </summary>
public class CreateLun : MonoBehaviour
{
    public GameObject prefab;//预制体

    float spacing = 10;     //间距
    int num = 5;            //个数
    float c;                //周长
    float r;                //半径
    float ang;              //每个角的弧度
    List<GameObject> cubes = new List<GameObject>();        //物品集合
    List<Transform> sortlist = new List<Transform>();    //位置集合
    float distance = 0;     //拖动的距离

    void Start()
    {
        //计算周长
        c = (1 + spacing) * num;
        //计算半径
        r = c / (Mathf.PI * 2);
        //计算每个角的弧度
        ang = 2 * Mathf.PI / num;

        for (int i = 0; i < num; i++)
        {
            cubes.Add(Instantiate(prefab, transform));
            float x = Mathf.Sin(i * ang) * r;
            float z = Mathf.Cos(i * ang) * r;
            cubes[i].transform.localPosition = new Vector3(x, 0, z);
            cubes[i].AddComponent<PMove>();
            sortlist.Add(cubes[i].transform);
        }
    }

    //差值移动
    public void Move(float dis)
    {
        distance -= dis;
        float moveang = distance / r;
        int count = cubes.Count;
        for (int i = 0; i < count; i++)
        {
            float x = Mathf.Sin(i * ang + moveang) * r;
            float z = Mathf.Cos(i * ang + moveang) * r;

            cubes[i].transform.localPosition = new Vector3(x, 0, z);
        }
        //给存起来的位置进行排序
        sortlist.Sort((a, b) =>
        {
            if (a.localPosition.z > b.localPosition.z)
                return 1;
            else if(a.localPosition.z == b.localPosition.z)
                return 0;
            else
                return -1;
        });
        int counts = sortlist.Count;
        for (int i = 0; i < counts; i++)
            sortlist[i].SetSiblingIndex(i);
        
    }
    //拖拽时鼠标抬起是的惯性计算
    public void Insrtin(float dis)
    {
        float timer = dis / speed;
        timer = timer > 2 ? timer : 2;
        DOTween.To((float index) =>
        {
            distance -= index;
            Move(index);
        }, dis, 0, timer).SetEase(Ease.InOutQuad).OnComplete(() =>
           {
               float moveang = Mathf.Sin(sortlist[sortlist.Count - 1].localPosition.x / r);
               float movedis = moveang / (Mathf.PI * 2) * c;
               DOTween.To((float indexs) =>
               {
                   distance = indexs;
                   Move(indexs);
               }, distance, distance + movedis, 2f);
               Agtne(sortlist[sortlist.Count - 1].GetComponent<CreateCube>().id);
           });
    }


    public void Agtne(int index)
    {
        int a = sortlist[sortlist.Count - 1].GetComponent<CreateCube>().id;
        int b = a - index;
        int s = num - Mathf.Abs(b);
        int d = s > Mathf.Abs(b) ? b : (b > 0 ? -s : s);
        float moveang = Mathf.Sin(sortlist[sortlist.Count - 1].localPosition.x / r) + (d * ang);
        float movedis = moveang / (Mathf.PI * 2) * c;
        DOTween.To((float indexss) =>
        {
            distance = indexss;
            Move(0);
        },distance,distance + movedis,2f).OnComplete(()=>
        {

        });
    }
}

 拖转3D物体时的代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PMove : MonoBehaviour
{
    Vector3 pos;

    //拖拽时的差值
    private void OnMouseDrag()
    {
        float z = Camera.main.WorldToScreenPoint(transform.position).z;
        Vector3 pos0 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, z));
        float dis = (pos0 - pos).x;
        transform.parent.GetComponent<CreateLun>().Move(dis);
        pos = pos0;
    }
    //鼠标按下是的位置记录
    private void OnMouseDown()
    {
        float z = Camera.main.WorldToScreenPoint(transform.position).z;
        pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, z));
    }
    private void OnMouseUp()
    {
        float z = Camera.main.WorldToScreenPoint(transform.position).z;
        Vector3 pos0 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, z));
        float dis = (pos0 - pos).x;
        transform.parent.GetComponent<CreateLun>().Insrtin(dis);
        pos = pos0;
    }
}

而想要3D物体移动时带有惯性效果,则可分为一下写法:

一、手写DoTween效果:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 3D轮转图
/// </summary>
public class CreateLun : MonoBehaviour
{
    public float dec = 0.8f;    //减速度
    public void Insrtin(float dis)
    {
        float time = Mathf.Abs(dis / dec);
        DT.To((a) =>
        {
            Move(a);
        }, dis, 0, time);
    }
}


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class DT : MonoBehaviour
{
    public Action<float> action;
    public float begin;
    public float end;
    public float time;
    float nowtime;

    public static DT To(Action<float> action, float begin, float end, float time)
    {
        GameObject dt = new GameObject("DT");
        DT doween = dt.AddComponent<DT>();
        doween.action = action;
        doween.begin = begin;
        doween.end = end;
        doween.time = time;
        doween.nowtime = Time.time;
        return doween;
    }

    // Update is called once per frame
    void Update()
    {
        if (Time.time - nowtime < time)
        {
            float t = Time.time - nowtime;
                float p = t / nowtime;
                float a = begin * (1 - p) + end * p;
                action(a);
        }
        else
        {
            
            action(end);
            Destroy(gameObject);
        }
    }
}

二、使用DoTween插件实现惯性效果

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using DG.Tweening;
using Newtonsoft.Json;
using System;

public class CreateLunBo : MonoBehaviour,IDragHandler,IEndDragHandler
{
    public GameObject prefab;   //预制体
    public int num = 9;         //数量
        //最大值   最小值     间距          拖动的距离
    float max = 1f, min = 0.5f, scaping = 1.5f, distance = 0;
    //半径    周长  每个角的弧度  速度
    float r, c, ang, speed = 10;
    List<GameObject> list = new List<GameObject>();
    List<Transform> sortlist = new List<Transform>();

    private void Move()
    {
        float moveAng = (distance / c) * Mathf.PI * 2;
        for (int i = 0; i < num; i++)
        {
            float x = Mathf.Sin(moveAng + i * ang) * r;
            float z = Mathf.Cos(moveAng + i * ang) * r;
            if (list.Count <= i)
            {
                list.Add(Instantiate(prefab, transform));
                list[i].transform.name = i.ToString();
                list[i].AddComponent<Call>();
                list[i].GetComponent<Call>().id = i;

                sortlist.Add(list[i].transform);
            }
            list[i].transform.localPosition = Vector3.right * x;
            float scale = 1 - (r + z) / (2 * r);
            list[i].transform.localScale = Vector3.one * ((max - min) * scale + min);
            if (list[i].transform.localScale.x < 0.75f)
            {
                list[i].SetActive(false);
            }
            else
            {
                list[i].SetActive(true);
            }
        }

        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;
        });
        int count = sortlist.Count;
        for (int i = 0; i < count; i++)
            sortlist[i].SetSiblingIndex(i);
    }
    public void OnDrag(PointerEventData eventData)
    {
        distance -= eventData.delta.x;
        Move();
    }
    public void OnEndDrag(PointerEventData eventData)
    {
        float timer = Mathf.Abs(eventData.delta.x) / speed;
        timer = timer > 2 ? timer : 2;
        DOTween.To((float index) =>
        {
            distance -= index;
            Move();
        },eventData.delta.x, 0, timer).SetEase(Ease.InOutQuad).OnComplete(() =>
        {
            float moveang = Mathf.Sin(sortlist[sortlist.Count - 1].localPosition.x / r);
            float movedis = moveang / (Mathf.PI * 2) * c;
            DOTween.To((float index1) =>
            {
                distance = index1;
                Move();
            }, distance, distance + movedis, 2f);
            Agtne(sortlist[sortlist.Count - 1].GetComponent<Call>().id);
        });
    }

    public void Agtne(int index)
    {
        int a = sortlist[sortlist.Count - 1].GetComponent<Call>().id;
        int b = a - index;
        int s = num - Mathf.Abs(b);
        int d = s > Mathf.Abs(b) ? b : (b > 0 ? -s : s);
        float moveang = Mathf.Sin(sortlist[sortlist.Count - 1].localPosition.x / r) + (d * ang);
        float movedis = moveang / (Mathf.PI * 2) * c;
        DOTween.To((float indexs) =>
        {
            distance = indexs;
            Move();
        }, distance, distance + movedis, 2f).OnComplete(() =>
        {

        });
    }
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值