Unity实现鼠标拖动3D物体

 更新时间:2020年10月13日 08:37:52   作者:罗松_ls  
这篇文章主要为大家详细介绍了Unity实现鼠标拖动3D物体,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

这篇博客实现一个小功能,通过鼠标拖动3D物体。我们知道,如果是拖动 UIUG 的控件的话,它是有接口可以使用的。但是3D物体就没有可直接使用的接口(或者说我没找到?),就需要我们自己写代码。既然如此,那我们就来实现以下这个功能。

首先先创建一个这样的场景

创建两个 cube 只是为了看清效果。然后给 摄像机添加一个 DragObject 脚本

using UnityEngine;
using System.Collections;

public class DragObject : MonoBehaviour {
  /// <summary>
  /// 将要拖动的物体
  /// </summary>
  private Transform dragGameObject;
  /// <summary>
  /// 获取射线需要碰撞的层
  /// </summary>
  private LayerMask canDrag;
  /// <summary>
  /// 直接从外部定义好层,简单理解
  /// </summary>
  public LayerMask canDrag2;
  /// <summary>
  /// 获得鼠标的位置和cube位置差
  /// </summary>
  private Vector3 offset;
  /// <summary>
  /// 是否点击到cube
  /// </summary>
  private bool isClickCube;
  /// <summary>
  /// 目标对象的屏幕坐标
  /// </summary>
  private Vector3 targetScreenPoint;

  // Use this for initialization
  void Start () {
    // LayerMask.GetMask("Cube"); 得到 名字为 Cube 的层的 2 进制
    // LayerMask.LayerToName(9); 得到一个 10 进制表示的层 的名字 这里既第十层
    // LayerMask.NameToLayer("Cube"); 得到 名字为 Cube 的层的 10 进制

    //使用位运算,因为 LayerMask (好像)是以2进制存储的 Layer 的层是以0开始
    canDrag = 1 << LayerMask.NameToLayer("Cube");
  }

  // Update is called once per frame
  void Update () {
    if (Input.GetMouseButtonDown(0))
    {
      if (CheckGameObject())
      {
        offset = dragGameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreenPoint.z));
      }
    }

    if (isClickCube)
    {
      //当前鼠标所在的屏幕坐标
      Vector3 curScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, targetScreenPoint.z);
      //把当前鼠标的屏幕坐标转换成世界坐标
      Vector3 curWorldPoint = Camera.main.ScreenToWorldPoint(curScreenPoint);
      dragGameObject.position = curWorldPoint + offset;
    }

    if (Input.GetMouseButtonUp(0))
    {
      isClickCube = false;
    }
  }

  /// <summary>
  /// 检查是否点击到cbue
  /// </summary>
  /// <returns></returns>
  bool CheckGameObject ()
  {
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hitInfo;
    if (Physics.Raycast(ray, out hitInfo, 100f, canDrag))
    {
      isClickCube = true;
      //得到射线碰撞到的物体
      dragGameObject = hitInfo.collider.gameObject.transform;
      targetScreenPoint = Camera.main.WorldToScreenPoint(dragGameObject.position);
      return true;
    }
    return false;
  }

}

添加此脚本后运行,就能成功看见效果。
今天这个工程比较简单,就不发工程了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#生成本地配置文件的实现示例

    C#生成本地配置文件的实现示例

    本文将介绍如何使用C#语言生成本地配置文件,以便为应用程序提供灵活的配置选项,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-01-01
  • 基于WPF实现路径图标控件

    基于WPF实现路径图标控件

    这篇文章主要介绍了如何利用WPF实现路径图标控件,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的小伙伴可以参考一下
    2023-07-07
  • c#数学表示法(后缀表示法)详解

    c#数学表示法(后缀表示法)详解

    什么是后缀表达式,查了下原来是一种比较特殊的数学表达式,有三种表达式:前缀表达式、中缀表达式和后缀表达式,下面我们使用示例学习一下
    2014-01-01
  • c# 类型转换

    c# 类型转换

    CLR最重要的特性之一就是类型安全性。在运行时,CLR总是知道一个对象是什么类型。调用GetType方法可以返回类型
    2012-10-10
  • C#使用TCP协议实现数据发送和接受的方法

    C#使用TCP协议实现数据发送和接受的方法

    这篇文章主要介绍了c#使用TCP协议实现数据发送和接受,使用TCP协议实现数据的发送和接受包括客户端和服务端两个部分,本文通过实例代码介绍的非常详细,需要的朋友可以参考下
    2024-04-04
  • C#使用selenium实现爬虫

    C#使用selenium实现爬虫

    这篇文章介绍了C#使用selenium实现爬虫的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C#实现合并多个word文档的方法

    C#实现合并多个word文档的方法

    这篇文章主要介绍了C#实现合并多个word文档的方法,是C#针对Word文档操作的一个非常重要的技巧,需要的朋友可以参考下
    2014-09-09
  • 使用JsonConverter处理上传文件的路径问题

    使用JsonConverter处理上传文件的路径问题

    我们上传一个文件,把文件保存到服务器上,会有一个明确的物理路径,由于需要从前端访问这个文件,还需要web服务器中的一个虚拟路径,我们可以使用JsonConverter 来自动处理一下,这篇文章主要介绍了使用JsonConverter处理上传文件的路径,需要的朋友可以参考下
    2022-12-12
  • C#并发编程之Task类详解

    C#并发编程之Task类详解

    Task是建立在线程池之上的一种多线程技术,它的出现使Thread成为历史。其使用方法非常简单,本文就来通过几个示例为大家讲讲它的具体使用吧
    2023-03-03
  • Winform实现将网页生成图片的方法

    Winform实现将网页生成图片的方法

    这篇文章主要介绍了Winform实现将网页生成图片的方法,类似于一般浏览器自带的网页生成图片的功能,需要的朋友可以参考下
    2014-09-09

最新评论