Unity实现鼠标拖拽多物体(拖拽单物体的拓展)

这篇具有很好参考价值的文章主要介绍了Unity实现鼠标拖拽多物体(拖拽单物体的拓展)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

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


目录

bool Drag

拖拽物体的实现

解决摄像机视角的影响


bool Drag

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

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

Drag为真时,关于拖拽计算的代码才会运行,这样就不会出现,同一套代码,你拖动一个球,其他所有球跟着动的情况。Unity实现鼠标拖拽多物体(拖拽单物体的拓展),Uinty引擎,unity,游戏引擎,游戏程序,关卡设计,c#,鼠标,目标检测

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轴上

Unity实现鼠标拖拽多物体(拖拽单物体的拓展),Uinty引擎,unity,游戏引擎,游戏程序,关卡设计,c#,鼠标,目标检测

解决摄像机视角的影响

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

Unity实现鼠标拖拽多物体(拖拽单物体的拓展),Uinty引擎,unity,游戏引擎,游戏程序,关卡设计,c#,鼠标,目标检测
没有旋转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

Unity实现鼠标拖拽多物体(拖拽单物体的拓展),Uinty引擎,unity,游戏引擎,游戏程序,关卡设计,c#,鼠标,目标检测
actuallyMoveDir实现的效果,旋转摄像机角度不会影响目标方向

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

完整代码

使用mainCamera,设置物体Rigidbody,MouseDrag需要添加进目标物体上文章来源地址https://www.toymoban.com/news/detail-843002.html

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<Rigidbody>();

    }

    // 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
    }
}

到了这里,关于Unity实现鼠标拖拽多物体(拖拽单物体的拓展)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • unity手指、鼠标滑动实现物体360度旋转、点击按钮实现物体旋转

    先创建一个ObjectRotation 脚本 之后将该脚本拖动到需要转动的object上 因为如果每次都真机模拟回很麻烦,所以我加入了让鼠标代替手指滑动的脚本来代替手指输入 同样的也是先创建一个MouseRow 脚本 最后我还需要某笔画沿着坐标旋转,代码如下: 里面有我的其他参数,如果读

    2024年02月11日
    浏览(65)
  • unity3D 鼠标滚轮实现物体的大小缩放

    鼠标滚轮响应函数是Input.GetAxis(\\\"Mouse ScrollWheel\\\"),函数返回值类型是float,向前滚是返回正数,向后滚是返回负数,且鼠标滚轮滑动单次函数返回值为0.1 利用返回值修改模型transform.localscale,实现模型缩放 鼠标滚轮一直向后滚,会看见模型逐渐变小,当变到很小到消失的时候,

    2024年02月08日
    浏览(81)
  • unity拖拽背包物体,并交换两个物体的信息

    前几天看了一个教程,背包物品交换。由于教程中使用的是ngui,很多代码需要使用UGUI重新写,因此苦恼了几天。 我遇到了以下问题,在此详细罗列,以记录错误的原因和修改的方法,供日后阅读查找。 一、背包中的物品在拖拽之后放入指定的空格子(问题1:不知道该怎么

    2024年04月15日
    浏览(49)
  • Unity3D实现鼠标悬浮UI或物体上显示文字信息

    Unity工具 大家好,我是心疼你的一切,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 本篇文章实现一个鼠标悬浮在ui或者物体上显示文字的功能 unity鼠标悬浮ui显示文字 鼠标进入UI执行的 鼠标离开UI执行的 鼠标在ui里滑动执行的 1. 2. 搭建比较简单,各位顺便搭建吧。

    2024年02月04日
    浏览(95)
  • Unity中拖拽3D物体并放入到指定位置

    1.新建一个cube作为我们用来拖拽的物体:  2.给该cube添加我们刚刚编写的脚本: 3.场景中新建几个cube命名为Taget3D,摆在不同的位置并将这些新的cube传入到ListTartgets中:    4.新建几个Image命名为TargetUI,放在不同的位置并传入到ListUITarget中 : 5.新建两个Button分别对应传入buttonU

    2024年02月11日
    浏览(99)
  • Unity 鼠标拖拽功能

    继承3个处理拖拽方法的接口IBeginDragHandler, IDragHandler, IEndDragHandler  

    2024年02月16日
    浏览(37)
  • Unity用鼠标拖拽UI,UI跟随鼠标移动

    先上效果 继承几个拖拽的接口 IBeginDragHandler, IDragHandler,IEndDragHandler 计算下偏移量,转换下坐标系 限制下可拖拽的范围,我设置的是canvas的大小 欢迎大佬多多来给萌新指正,欢迎大家来共同探讨。 如果各位看官觉得文章有点点帮助,跪求各位给点个“一键三连”,谢啦~ 声明

    2024年02月06日
    浏览(82)
  • Unity 鼠标控制 UI 放大、缩小、拖拽

    2024年02月12日
    浏览(67)
  • Unity 鼠标拖动旋转物体,并且物体不会越转越乱

    用Mathf.Abs(绝对值)计算鼠标水平和竖直方向谁的位移更大,减少因为一丢丢的其他方向移动导致的物体微幅旋转影响后面物体旋转会越来越混乱。这样可以让物体旋转更好的单个方向进行旋转。 代码如下:

    2024年02月15日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包