目录

第一种:物体跟随鼠标移动。

第二种:鼠标拖动物体运动。

第三种:鼠标点到哪,物体运动到哪。


第一种:物体跟随鼠标移动。

描述:鼠标左键点击物体,将物体拾起,松开鼠标左键,物体跟随鼠标光标移动。再次点击鼠标左键,物体不在跟随鼠标,处于静止状态。

实现方法:射线。

1657678042844

写在前面:什么是射线?

简单来说就是当鼠标点击某个物体时,通过摄像机camera发射射线,射线与物体碰撞在一个点上。我们通过这个点找到该点对应的物体,先判断该物体是否是我们想要移动的(是否为可以移动的)。

如果是,那我们就拿到要操作的对象了,接下来就是让其坐标位置和鼠标位置保持一致即可。

具体解释和详细使用方法读者可自行查阅相关文献。

由此我们可以得出,我们要先声明一个射线的变量,还有碰撞点,由于有碰撞点,我们就必需为物体添加刚体组件。为了判断是不是我们要的物体,就定义一个布尔值。此外,为了区分鼠标点击这一动作是拾起还是放下物体,我们要声明一个标志量flag。为了得到该碰撞点对应的物体,我们要声明一个GameObject组件来得到它。

    private Ray ra;//声明射线private RaycastHit hit;//声明碰撞点private bool is_element =false;//判断是否是我们要的物体private int flag = 0;//标志量private GameObject Element;//控件

接下来就是干正事儿了。

判断鼠标是否按下:

if (Input.GetMouseButtonDown(0)){}

鼠标按下后,摄像机往按下位置发射射线。

    ra = Camera.main.ScreenPointToRay(Input.mousePosition);

判断射线是否跟物体发生碰撞得到碰撞点hit,并且同时判断该点对应的物体是不是我们要的。

判断物体是不是我们要的,这里我使用的是判断其标签是不是'element',因此应该给先给物体添加一个标签。

以上检测完后将布尔值设为true,并将碰撞点对应的物体给Element。

if (Physics.Raycast(ra, out hit)&&hit.collider.tag=="element"){is_element = true;Element = hit.collider.gameObject;}

判断鼠标按下是拾起还是放下。

这里我规定,鼠标拾起物体时,flag=1,再次点击flag=0。

总的判断部分代码为:

if (Input.GetMouseButtonDown(0)){ra = Camera.main.ScreenPointToRay(Input.mousePosition);if (Physics.Raycast(ra, out hit)&&hit.collider.tag=="element"){is_element = true;Element = hit.collider.gameObject;Debug.Log(Element.transform.position);if (flag == 0){flag = 1;}else{flag = 0;}}}

改变物体位置和鼠标位置一致。

我们要先得到鼠标的位置。

鼠标只有x和y轴,为了和物体位置一致,这里将鼠标的z轴设置为物体的坐标。

Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y,Element.transform.position.z);

由于鼠标位置是屏幕坐标,而物体坐标是世界坐标,那我们就要把鼠标的屏幕坐标换成世界坐标。

Vector3 mouseSToW = Camera.main.ScreenToWorldPoint(mousePos);

细心的人可以发现,这里有个“陷阱”。

我们在把鼠标的二位坐标用三位坐标表示时,其z轴就是物体的世界坐标的位置,然后我们之后又把它当作屏幕坐标转化成世界坐标,那么最后的坐标肯定和以前的不一样了。

所以我们要先将物体的世界坐标转化成成屏幕坐标,在把屏幕坐标的z轴坐标给鼠标的屏幕坐标,然后一同转化成世界坐标。然后将得到的世界坐标给物体。

Vector3 targetScreenPos = Camera.main.WorldToScreenPoint(Element.transform.position);
Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y,targetScreenPos.z);
Element.transform.position = Camera.main.ScreenToWorldPoint(mousePos);

当flag=1时,我们是拾起物体的,因此在flag变为0之前,我们的物体都是跟着鼠标移动的。

因此以上操作都是在flag==1以及is_element=true的条件下进行的。

if (flag == 1&&is_element){Vector3 targetScreenPos = Camera.main.WorldToScreenPoint(Element.transform.position);Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y,targetScreenPos.z);Element.transform.position = Camera.main.ScreenToWorldPoint(mousePos);}

代码汇总得:

using System.Collections;
using System.Collections.Generic;
using System.Linq.Expressions;
using Unity.VisualScripting;
using UnityEngine;public class camera : MonoBehaviour {//public Camera ca;private Ray ra;private RaycastHit hit;private bool is_element =false;private int flag = 0;private GameObject Element;// Use this for initializationvoid Start () {}// Update is called once per framevoid Update () {if (Input.GetMouseButtonDown(0)){ra = Camera.main.ScreenPointToRay(Input.mousePosition);if (Physics.Raycast(ra, out hit)&&hit.collider.tag=="element"){is_element = true;Element = hit.collider.gameObject;if (flag == 0){flag = 1;}else{flag = 0;}}}if (flag == 1&&is_element){Vector3 targetScreenPos = Camera.main.WorldToScreenPoint(Element.transform.position);Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y,targetScreenPos.z);Element.transform.position = Camera.main.ScreenToWorldPoint(mousePos);}}
}

第二种:鼠标拖动物体运动。

描述:长按鼠标左键,物体跟随鼠标移动,松开鼠标左键,物体停止运动。

实现方法:协程或者射线。

有了前面的坐标转换基础,再加上对协程的基本了解,这个实现是非常容易的,我就直接上代码吧。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Cooperation : MonoBehaviour
{IEnumerator OnMouseDown()    //使用协程{Vector3 targetScreenPos = Camera.main.WorldToScreenPoint(transform.position);//三维物体坐标转屏幕坐标//将鼠标屏幕坐标转为三维坐标,再计算物体位置与鼠标之间的距离var offset = transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreenPos.z));while (Input.GetMouseButton(0)){//将鼠标位置二维坐标转为三维坐标Vector3 mousePos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreenPos.z);//将鼠标转换的三维坐标再转换成世界坐标+物体与鼠标位置的偏移量var targetPos = Camera.main.ScreenToWorldPoint(mousePos) + offset;transform.position = targetPos;yield return new WaitForFixedUpdate();//循环执行}}}}

使用射线的方法与之类似,这里就不在赘述。

第三种:鼠标点到哪,物体运动到哪。

描述:类似于英雄联盟的移动方式,鼠标点击平面任意位置,物体立即朝该方向移动。

1657681859641

首先,对移动物体和地面进行bake,操作如下:

选中Cube,点击window—>AI—>Navigation

然后将Navigation Static勾选上

之后选择bake,地面和移动物体(Cube)都要勾选上。

代码我就直接给了,比较容易理解。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;public class Nvgt : MonoBehaviour
{private NavMeshAgent navMeshAgent;void Start(){navMeshAgent = gameObject.GetComponent<NavMeshAgent>();//初始化navMeshAgent}void Update(){if (Input.GetMouseButtonDown(0))//鼠标左键点下  {Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//住摄像机向鼠标位置发射射线 RaycastHit hit;if (Physics.Raycast(ray, out hit))//射线检验 {if (hit.collider.gameObject.tag == "Plane"){navMeshAgent.SetDestination(hit.point);//mHit.point就是射线和plane的相交点,实为碰撞点}}}}
}

Unity鼠标带动物体运动的三种方法相关推荐

  1. unity 控制物体移动的三种方法

    可以使按照指令物体移动的方法 一.常规方法 //四个方向if (Input.GetKey(KeyCode.W)){transform.Translate(Vector3.forward*moveSpe ...

  2. unity中控制游戏物体移动最基本的三种方法

    **unity**中控制游戏物体移动的最基本的三种方法 第一种移动方法-transform.Translate,游戏物体按照你给的方向和速度进行运动 代码如下: Public float speed; ...

  3. linux电脑滚轮不能用,图文详解电脑鼠标滚轮不动了怎么办_电脑鼠标滚轮不能用的三种解决方法-系统城...

    近期,许多小伙伴发现电脑鼠标滚轮失灵了,无缘无故的就无法使用,浏览网页玩游戏都没办法继续进行,真的很麻烦.针对电脑鼠标滚轮不动了的故障,小编收集整理具体原因和解决方法给大家,希望大家采纳! 原因一:鼠 ...

  4. 三维坐标系带偏航角俯仰角_浅谈三维旋转的三种方法及差异

    概述 在3D图形学中,几何变换大致分为三种:平移变换(Translation).缩放变换(Scaling).旋转变换(Rotation),而其中又以旋转变换(Rotation)最为复杂,通常旋转变换( ...

  5. 拖动精灵的三种方法比较

     构建Ball精灵: Ball.as package  {     import flash.display.Sprite; public class Ball extends Sprite      ...

  6. Unity3D中的SendMessage使用(消息传递的三种方法)

    转载自 Unity3D中的SendMessage使用(消息传递的三种方法) 0 概述 Unity提供的消息推送机制可以非常方便我们的脚本开发,它实现的是一种 伪监听者模式,利用的是反射机制. 1 常用 ...

  7. 测试Python下载图片的三种方法

    简 介: 通过Python软件包对网络URL图片链接进行下载,可以加快后期处理.本文测试了urllib, request两个软件包对图片进行下载效果.如果图片原网页有了防止下载机制,是无法下载图片. ...

  8. linux ie8找不到,ie浏览器不见了怎么办 三种方法搞定【图文教程】

    ie浏览器是我们平时常用来进行上网的工具之一,我们可以通过ie浏览器看视频.新闻,还可以查阅资料等等.但有时候,我们会发现桌面上的ie浏览器突然不见了,给我们带来不小的麻烦.那么遇到这种情况,我们要怎 ...

  9. mac 如何查看anaconda的路径_Mac OS如何直接查看gif图片?分享MAC直接查看gif图片的三种方法...

    想必许多刚入手Mac的用户在浏览GIF图片文件时,会发现Mac不能直接打开GIF,因此有的用户为了方便查看还特意去下载了GIF的图片查看器,其实在Mac中有多种能够直接打开GIF的方法,用户无需任何第 ...

  10. 如何安全的在不同工程间安全地迁移asset数据?三种方法

    如何安全的在不同工程间安全地迁移asset数据?三种方法 答: 1.将Assets和Library一起迁移 2.导出包package 3.用unity自带的assets Server功能 posted ...

最新文章

  1. form表单刷新_《大胖 ? 小课》- 不用 js 实现文件无刷新上传
  2. lingo变量无限制版本_LINGO笔记
  3. 为什么函数式编程很重要:不一样的白板图
  4. 修改了模板文件tpl如何立即生效_Views视图与模板
  5. 万字长文带你从零开始认识机器学习
  6. (59)FPGA面试题-什么是有限的状态机?有限状态机可分为几类,分别是什么?
  7. 多线程编程进阶——Java类库中的锁
  8. aix oracle集群日志,在AIX环境下实施Oracle 集群RAC的结构 文平
  9. 谭晓生:如何面对IoT时代的安全新挑战?
  10. 怎么隐藏运行linux控制台,Win10秘笈:如何隐藏任意程序运行界面? - IT之家
  11. 这几个小工具也太好用了
  12. python爬房源信息_Python爬虫-爬取300个短租网房源信息
  13. JPEG压缩中质量因子和量化矩阵之间的关联
  14. 单独备份config配置文件 (来自老梁邮件)
  15. 创建可引导的 macOS High Sierra 安装 U 盘
  16. 独家 | 零基础入门优化问题
  17. flowable工作流简单请假流程,自定义完成的流程图表颜色字体以及连接线的颜色字体。
  18. 电子邮箱是什么,电子邮箱注册值得入手的邮箱都在这!
  19. 蓝桥杯 青少年创意编程大赛 scratch 组(一)
  20. openGauss Summit 2021 | 汇聚数据库创新力量 逐梦数字时代星辰大海

热门文章

  1. 吴军老师的《计算之魂》部分重点摘要
  2. [oracle]Oracle数据库安全管理
  3. 高性能计算机英语,“超级计算机”英语怎么说
  4. html给页面加背景特效怎么加,给网页加上js特效
  5. 使用keras框架训练神经网络时显卡内存使用很大很大的解决方案
  6. win7电脑无线网变身WiFi热点,让手机、笔记本共享上网
  7. 从纹理中生成法线贴图
  8. Computational principles of synaptic memory consolidation(2016 Nature Neuroscience)
  9. android 9 vxp 闪退,XPrivacyLua限制了权限的应用无法打开
  10. 外贸怎么开发客户?这些你不一定知道