Unity实现鼠标拖拽多物体(拖拽单物体的拓展)
创始人
2024-12-17 09:06:53
0

学习了B站UP主OneCredit【Unity快速教学】鼠标拖曳甩动物件BV1qK4y1d7iZ的教学视频后

拓展了一下功能,实现多个物体也可以拖拽,互不受影响

主要是做了一个检测,在鼠标上物体才能被拖拽


目录

bool Drag

拖拽物体的实现

解决摄像机视角的影响


bool Drag

绑定刚体,写好需要用到的变量

Drag用于判断鼠标是否在物体上,只有鼠标放在物体上或者拖拽物体,Drag才为真

Drag为真时,关于拖拽计算的代码才会运行,这样就不会出现,同一套代码,你拖动一个球,其他所有球跟着动的情况。

using UnityEngine; public class MouseDrag : MonoBehaviour {     public float moveForce = 10;     public Rigidbody mD;//绑定目标刚体     Vector3 startPos;//起点     Vector3 endPos;//终点     Vector3 moveDir;//moveDirection     Vector3 actualMoveDir;//实际的moveDirection     private bool Drag;//是否在拖拽-检测多物体拖拽      private void OnMouseEnter()     {         Drag = true;         print("enter work");//当鼠标在物体上     }     private void OnMouseExit()     {         Drag = false;         print("exit work");//当鼠标离开物体     }     private void OnMouseDrag()     {         Drag = true;         print("drag work");//当鼠标在物体上->单击->拖拽     }

拖拽物体的实现

实际上是先得到拖拽开始时鼠标的初始位置,拖拽动作完成瞬间,得到松手时鼠标位置,得到两个向量,分别为startPos和endPos

endPos减去startPos就能得到以物体为起点指向鼠标松开位置的一个向量

  void Update()     {         if (Drag)//只有if为真时,即鼠标在物体上或者拖拽该物体时,以下代码才会生效         {             if (Input.GetKeyDown(KeyCode.Mouse0))//KeyDown鼠标按下瞬间startPos收到鼠标松手位置             {             startPos = Camera.main.ScreenToViewportPoint(Input.mousePosition);                 //startPos收到鼠标起始位置             }             if (Input.GetKeyUp(KeyCode.Mouse0))//Keyup,鼠标松开瞬间endPos收到鼠标松手位置             {                 endPos = Camera.main.ScreenToViewportPoint(Input.mousePosition);                 Vector3 dir = endPos - startPos;                 moveDir = new Vector3(dir.x, 0, dir.y);                 actualMoveDir = Quaternion.AngleAxis(Camera.main.transform.eulerAngles.y, Vector3.up) * moveDir;                  movetheball();                 OnMouseExit();             }         }     void movetheball()             {                 mD.AddForce(actualMoveDir * moveForce, ForceMode.Impulse);                 //给刚体对象mD添加一个力,向量是真实位移actualMoveDir * 力moveForce * (力的作用模式)给物体一个瞬间的力 ForceMode.Impulse             }         }     }

关于Camera.ScreenToViewportPoint 描述为将 position 从屏幕空间变换为视口空间

参考https://docs.unity.cn/cn/current/ScriptReference/Camera.ScreenToViewportPoint.html

参数Input.mousePosition  意为以像素坐标表示的当前鼠标位置

得到的向量放进startPos中,endPos同理

Vector3 dir = endPos - startPos;
物体要移动的方向 = 松手处末向量 - 点下鼠标处初始向量

这样得到的向量,缺少Z值,因为Input.mousePosition没有提供Z方向(X,Z为平面上的方向)

但是物体需要在XZ平面上移动

所以moveDir = new Vector3(dir.x, 0, dir.y);实际上是把dir的y值放到了Z轴上

解决摄像机视角的影响

但是新的问题是,如果你移动摄像机的Y轴,当你拖动物体时,物体会依然按照摄像机原方向移动

没有旋转moveDir的y轴:当摄像机Y轴转动后,物体不按照预定方向前进

actualMoveDir = Quaternion.AngleAxis(Camera.main.transform.eulerAngles.y, Vector3.up) * moveDir;
这个代码的作用是--旋转Y轴,如果摄像机的Y轴被旋转了,你得让moveDir同步旋转,物体才会跟着你的鼠标拖动方向走~

Transform.eulerAngles 表示世界空间中的旋转

Quaternion.AngleAxis的用法:Quaternion-AngleAxis - Unity 脚本 API

public static Quaternion AngleAxis (float angle, Vector3 axis);

transform.rotation = Quaternion.AngleAxis(转动的角度, 围绕的轴);

代码中是以摄像机的y轴旋转了多少放到参数1,围绕转动的轴为 Vector3.up(y轴)

得到旋转和摄像机相同y轴数值的actualMoveDir

actuallyMoveDir实现的效果,旋转摄像机角度不会影响目标方向

最终无论方向怎么改变,只要你能看到物体,拖动它时,总能向着你觉得它应该去的方向前进。

完整代码

使用mainCamera,设置物体Rigidbody,MouseDrag需要添加进目标物体上

using UnityEngine;  public class MouseDrag : MonoBehaviour {     public float moveForce = 10;     public Rigidbody mD;//绑定目标刚体     Vector3 startPos;//起点     Vector3 endPos;//终点     Vector3 moveDir;//moveDirection     Vector3 actualMoveDir;//实际的moveDirection     private bool Drag;//是否在拖拽-检测多物体拖拽      private void OnMouseEnter()     {         Drag = true;         print("enter work");//当鼠标在物体上     }     private void OnMouseExit()     {         Drag = false;         print("exit work");//当鼠标离开物体     }     private void OnMouseDrag()     {         Drag = true;         print("drag work");//当鼠标在物体上->单击->拖拽      }       // Start is called before the first frame update     void Start()     {         //前面有声明刚体对象 Rigidbody mD         //这里是在游戏运行前,获取当前游戏对象的刚体组件         mD = GetComponent();      }      // Update is called once per frame     void Update()     {           if (Drag)         {             if (Input.GetKeyDown(KeyCode.Mouse0))//KeyDown鼠标按下瞬间startPos收到鼠标松手位置             {                 //关于Camera.ScreenToViewportPoint    意为将 position 从屏幕空间变换为视口空间                 //屏幕空间(屏幕空间以像素定义。屏幕的左下角为(0, 0),右上角 为(pixelWidth, pixelHeight)。z 位置为与摄像机的距离)                 //视口空间(摄像机左下角为 (0,0),右上角为 (1,1),Z为与摄像机的距离)                 //https://docs.unity.cn/cn/current/ScriptReference/Camera.ScreenToViewportPoint.html                 //参数Input.mousePosition  意为以像素坐标表示的当前鼠标位置。                 //https://docs.unity.cn/cn/current/ScriptReference/Input-mousePosition.html                   startPos = Camera.main.ScreenToViewportPoint(Input.mousePosition);                 //startPos收到鼠标起始位置             }              if (Input.GetKeyUp(KeyCode.Mouse0))//Keyup,鼠标松开瞬间endPos收到鼠标松手位置             {                 endPos = Camera.main.ScreenToViewportPoint(Input.mousePosition);//同上的操作                  Vector3 dir = endPos - startPos;                 //松手处末向量 - 点下鼠标处初始向量 = 物体要移动的方向                 //一个ADB三角,起点为世界原点,AD - AB = DB                  moveDir = new Vector3(dir.x, 0, dir.y);                 //Input.mousePosition没有提供Z方向(X,Z为平面上的方向)                 //将临时向量dir的y方向放到moveDir的z方向上                  actualMoveDir = Quaternion.AngleAxis(Camera.main.transform.eulerAngles.y, Vector3.up) * moveDir;                 //旋转Y轴,如果你摄像机的Y轴被旋转了,你要让moveDir同步旋转,才能让物体跟着你的鼠标走                  movetheball();                 OnMouseExit();              }         }     }      void movetheball()     {         mD.AddForce(actualMoveDir * moveForce, ForceMode.Impulse);         //给刚体对象mD添加一个力,向量是真实位移actualMoveDir * 力moveForce * (力的作用模式)给物体一个瞬间的力 ForceMode.Impulse     } }

相关内容

热门资讯

第1分钟了解!游戏浙江大厅脚本... 第1分钟了解!游戏浙江大厅脚本修改,科乐辅助工作室,指南教程(有挂规律)-哔哩哔哩该软件可以轻松地帮...
七分钟了解!微乐四川辅助,微乐... 七分钟了解!微乐四川辅助,微乐小程序免费黑科技下载,步骤教程(确实有挂)-哔哩哔哩1)微乐小程序免费...
第5分钟了解!土豪辅助,新道游... 第5分钟了解!土豪辅助,新道游辅助软件下载,策略教程(有挂分析)-哔哩哔哩1、全新机制【新道游辅助软...
第四分钟了解!中至鹰潭亲友圈辅... 第四分钟了解!中至鹰潭亲友圈辅助,兴动海满麻浆辅助,经验教程(有挂攻略)-哔哩哔哩1、玩家可以在中至...
7分钟了解!闲逸辅助器,广西老... 7分钟了解!闲逸辅助器,广西老友修改器,法子教程(有挂教程)-哔哩哔哩1、广西老友修改器脚本辅助下载...
第3分钟了解!红黑大战控制系统... 第3分钟了解!红黑大战控制系统,拱趴大菠萝玩的是运气吗,练习教程(果真有挂)-哔哩哔哩1、游戏颠覆性...
第九分钟了解!家乡大二辅助免费... 第九分钟了解!家乡大二辅助免费,奇迹陕西游戏辅助挂,妙招教程(有挂助手)-哔哩哔哩奇迹陕西游戏辅助挂...
8分钟了解!海南琼崖海南辅助功... 8分钟了解!海南琼崖海南辅助功能,传送屋辅助,模板教程(有挂详情)-哔哩哔哩1、海南琼崖海南辅助功能...
第5分钟了解!天天开心王国辅助... 第5分钟了解!天天开心王国辅助器,手机填大坑辅助器,策略教程(真实有挂)-哔哩哔哩天天开心王国辅助器...
五分钟了解!德普之星透视挂,川... 五分钟了解!德普之星透视挂,川南九九辅助,攻略教程(有挂细节)-哔哩哔哩1、每一步都需要思考,不同水...