实现3D轮转图

       首先,根据轮转图个数和间距分别计算周长、半径、每个物体之间的弧度,根据三角函数计算每个物体的具体坐标位置,将生成的物体存入集合。

        拖拽物体旋转,获取鼠标拖拽的距离和拖拽物体的位置坐标,计算拖拽的的距离,代码如下

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 OnMouseDrag()
    {
        float z = Camera.main.WorldToScreenPoint(transform.position).z;
        Vector3 pos0 = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, z));
        transform.parent.GetComponent<Rotate3D>().Move(pos0.x - pos.x);
        pos = pos0;
    }

调用物体移动的方法传入移动距离参数,根据距离计算移动的弧度重新设置每个物体的坐标位置

代码如下

    public void Move(float dis)
    {
        distance += dis;
        float moveAng = distance / r;
        for (int i = 0; i < n; i++)
        {
            float x = Mathf.Sin(i * ang+ moveAng) * r;
            float z = Mathf.Cos(i * ang+ moveAng) * r;
            list[i].transform.localPosition = new Vector3(x, 0, z);
        }
    }

让物体具有旋转的惯性,首先获得抬起鼠标时的距离,根据减速速度计算得出减速所需要的时间

使用DoTween实现惯性效果

惯性结束再让物体对齐根据物体距离零点坐标的距离z轴来判断当前转到的是哪个物体

调用sortlist集合中的Sort方法排序,找出距离零点坐标的最小值sortlist[0]

根据sortlist[0]的位置来计算需要对齐的角度和移动的距离,并根据减速度计算出所需时间,

使用DoTween来实现对齐效果,代码如下

    public void Align()
    {
        sortlist.Sort((a, b) =>
        {
            if (a.localPosition.z< b.localPosition.z)
            {
                return -1;
            }
            else if (a.localPosition.z > b.localPosition.z)
            {
                return 1;
            }
            else
            {
                return 0;
            }
        });
        float AlignAng = Mathf.Atan(sortlist[0].localPosition.x /                             sortlist[0].localPosition.z);
        float Aligndis = AlignAng * r;
        float time = Mathf.Abs(Aligndis) / 1;
        DT.To((a) =>
        {
            Move(a - distance);
        }, distance, distance - Aligndis, time);
    }

手写DoTween代码如下

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

public class DT : MonoBehaviour
{
    float nowTime, startTime, start, end, time;
    Action<float> action;
    Action complete;
    // Start is called before the first frame update
    public static DT To(Action<float> action,float start,float end,float time)
    {
        GameObject obj = new GameObject("DT");
        DT dt = obj.AddComponent<DT>();
        dt.action = action;
        dt.start = start;
        dt.time = time;
        dt.end = end;
        return dt;
    }

    void Start()
    {
        startTime = Time.time;
    }

    // Update is called once per frame
    void Update()
    {
        if (nowTime<time)
        {
            nowTime = Time.time - startTime;
            float p = nowTime / time;
            float now = (end - start) * p + start;
            action(now);
            if (nowTime > time)
            {
                nowTime = time;
                if (complete!=null)
                {
                    complete();
                }
                Destroy(gameObject);
            }
        }
    }
    public void OnComplete(Action t)
    {
        this.complete = t;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值