栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

Unity 实现鼠标拖拽物体沿路径移动并且旋转

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Unity 实现鼠标拖拽物体沿路径移动并且旋转

Unity 实现鼠标拖拽物体沿路径移动并且旋转

最近策划提了一个需求,要求拖拽物体要按照规定的路径随便移动,移动到终点后停止移动,还要从开始点到结束点一共旋转一圈。
首先需要自己创建路径点,直接在场景中添加一些空物体当做路径点就可以。
拖拽物体进行移动,需要判断你是往哪个方向拖动的,这就要用到向量的点乘来计算向量相似度。看下一帧移动方向是和下一个目标点方向更相似还是和上一个目标点方向更相似。
物体旋转的话就需要计算当前位置应该的旋转角度。
下面,上代码。

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


public class DragAtPath : MonoBehaviour
{
 ///  是否开始拖拽物体按照轨道移动 
 public bool isStartDragWithPath = true;
 private Vector3 mousePos;            //鼠标按下的位置
 private Vector3 nextMousePos;
 public List DragPath = new List();
 private int index = 0;
 public List rotate = new List();
 private float MaxRotate = 360;
 void Start()
 {
     CacleRotate();
 }
 private void OnMouseDown()
 {
     mousePos = Input.mousePosition;
 }

 /// 
 /// 计算各个节点物体的旋转应该是多少
 /// 
 private void CacleRotate()
 {
     float pathLenth = 0;
     List pathDis = new List();
     for (int i = 0; i < DragPath.Count-1; i++)
     {
         float dis = Vector3.Distance(DragPath[i].position, DragPath[i + 1].position);
         pathDis.Add(dis);
         pathLenth += dis;
     }
     for (int i = 0; i < DragPath.Count; i++)
     {
         if (i==0)
         {
             rotate.Add(Vector3.zero);
         }
         else
         {
             rotate.Add(rotate[i - 1] + new Vector3(0, 0, MaxRotate * (pathDis[i-1]/pathLenth)));
         }
     }
 }

 private void OnMouseDrag()
 {
     ExecuteDragWithPath();
 }

 ///  执行按照路径拖拽物体 
 private void ExecuteDragWithPath()
 {
     if (isStartDragWithPath)
     {
         nextMousePos = Input.mousePosition;
         Vector3 current1 = mousePos - nextMousePos;
         Vector3 current = current1.normalized;
         current = new Vector3(-current.x, -current.y, current.z);//根据摄像机的方向不同,正负也不同
         Vector3 comperLast, compareNext;
         comperLast = transform.position - DragPath[index].position;
         comperLast = comperLast.normalized;
         compareNext = transform.position - DragPath[index + 1].position;
         compareNext = compareNext.normalized;

         float DotNext = Vector3.Dot(current, compareNext);//计算拖拽向量和下一个目标节点的向量点积
         float dotLast = Vector3.Dot(current, comperLast);//计算拖拽向量和上一个目标节点的向量点积
         float speed = current1.magnitude;//拖拽的长度
         if (speed <= 0.1f)
         {
             return;
         }
         if (DotNext < dotLast)//如果上一个的相似度低于下一个,意味着拖拽方向更近似于下一个,所以向下一个节点处移动
         {
             transform.position = Vector3.MoveTowards(transform.position, DragPath[index + 1].position, Time.deltaTime * speed);
             Vector3 rot = CacleNextRotate();
             transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(rot), 1);
             if (Vector3.Distance(transform.position, DragPath[index + 1].position) < 0.01f)
             {
                 transform.rotation = Quaternion.Euler(rotate[index + 1]);
                 transform.position = DragPath[index + 1].position;
                 index++;
                 if (index == DragPath.Count - 1)
                 {
                     isStartDragWithPath = false;
                 }
             }
         }
         else
         {

             transform.position = Vector3.MoveTowards(transform.position, DragPath[index].position, Time.deltaTime * speed);
             Vector3 rot = CacleNextRotate();
             transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler(rot), 1); if (Vector3.Distance(transform.position, DragPath[index].position) < 0.01f)
             {
                 transform.rotation = Quaternion.Euler(rotate[index]);
                 transform.position = DragPath[index].position;
                 index--;
                 if (index == -1)
                 {
                     index = 0;
                 }
             }
         }
         mousePos = nextMousePos;
     }
 }

 /// 
 /// 计算下一个旋转
 /// 
 /// 
 private Vector3 CacleNextRotate()
 {
     float dir = Vector3.Distance(DragPath[index + 1].position, DragPath[index].position);//计算两个位置点的距离
     float cur = Vector3.Distance(transform.position, DragPath[index].position);//计算当前位置距离上一个点的距离
     Vector3 rot = rotate[index + 1] * (cur / dir) + (1 - (cur / dir)) * rotate[index];
     return rot;
 }

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/901392.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号