Unity使用ConfigurableJoint实现物理拖拽物体

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

我们如何在游戏中实现拖拽物体呢,如果仅仅是让拖拽坐标,可能没有物理效果,这里可以使用Joint来实现。

场景

首先我们在场景中放置道具。
Unity使用ConfigurableJoint实现物理拖拽物体
如图,我们放置一个圆柱体Cylinder,一个Sphere球体,和地面。
圆柱体就是我们要拖动的物体,红色球体是我们点击的位置,白色的地面放置圆柱体掉下去。

我们在圆柱体上增加刚体,球体上也增加刚体,球体的Rig需要勾选运动学,因为Joint组件需要。

我们要实现鼠标点击圆柱体,拖拽,圆柱体跟随鼠标左右上下移动。

我们添加一个脚本CDrag挂在球体上。
Unity使用ConfigurableJoint实现物理拖拽物体
变量HandRig就是球体的刚体。
变量Target就是圆柱体。

鼠标按下

在Update中,我们先写鼠标点击事件。我们要做的事情就是鼠标按下后,我们发射射线检测是否碰到圆柱体,然后把红色的球体移动过去,并且给圆柱体增加ConfigurableJoint,把他们两个联系起来,这样圆柱体就跟随球体了。代码如下:

	void Hand(float x, float y)
    {
        Vector3 at = new Vector3(x, y, myCamera.transform.position.z);
        Ray ray = myCamera.ScreenPointToRay(at);
        RaycastHit hit;
        Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 1f);
        bool b = Physics.Raycast(ray, out hit, 100f, 1 << LayerMask.NameToLayer("Default"));
        if (b && hit.collider != null && hit.collider.name.Equals("Cylinder"))
        {
            HandRig.transform.position = hit.point;
            if (joint != null)
                Destroy(joint);
            joint = target.gameObject.AddComponent<ConfigurableJoint>();
            joint.connectedBody = HandRig;
            joint.xMotion = ConfigurableJointMotion.Locked;
            joint.yMotion = ConfigurableJointMotion.Locked;
            joint.zMotion = ConfigurableJointMotion.Locked;
            handupdis = Vector3.Distance(hit.point, myCamera.transform.position);
        }
    }
    
	void Update()
    {

        if (Input.GetMouseButtonDown(0))
        {
            Hand(Input.mousePosition.x,Input.mousePosition.y);
        }
    }

我们看到,在射线碰到圆柱体后,我们把红球改到了碰撞点位置,并且给target(圆柱体)增加了ConfigurableJoint,并且让他connectedBody到红球,并且设置x,y,z可以自由移动。最后handupdis是为了下面的移动准备的。

鼠标移动

然后我们再来处理移动
当我们移动的时候,我们只要移动球体,那么因为Joint被绑定到球体了,他也会跟着移动了。

		if (Input.GetMouseButton(0))
        {
            Move(Input.mousePosition);
        }
	private void Move(Vector3 pos)
    {
        pos.z = handupdis;
        Vector2 world = myCamera.ScreenToWorldPoint(pos);
        
        HandRig.transform.position = world;
    }

我们来看看效果。
Unity使用ConfigurableJoint实现物理拖拽物体
有没有发下一个问题,红球点击圆柱体下面的时候,被拾取的点还是在顶部,我们需要计算锚点。

增加这行代码就舒服多了。

joint.anchor = joint.transform.InverseTransformPoint(hit.point);

最后

我们把鼠标放开也一起写了,放上全部代码。

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

//UTF8支持
public class CDrag : MonoBehaviour
{
    [SerializeField] Rigidbody HandRig;
    [SerializeField] Transform target;
    Camera myCamera;
    ConfigurableJoint joint;

    float handupdis;
    Vector2 startpos;
    // Start is called before the first frame update
    void Start()
    {
        myCamera = Camera.main;
    }

    void Hand(float x, float y)
    {
        Vector3 at = new Vector3(x, y, myCamera.transform.position.z);
        Ray ray = myCamera.ScreenPointToRay(at);
        RaycastHit hit;
        Debug.DrawRay(ray.origin, ray.direction * 100f, Color.red, 1f);
        bool b = Physics.Raycast(ray, out hit, 100f, 1 << LayerMask.NameToLayer("Default"));
        if (b && hit.collider != null && hit.collider.name.Equals("Cylinder"))
        {
            HandRig.transform.position = hit.point;
            if (joint != null)
                Destroy(joint);
            joint = target.gameObject.AddComponent<ConfigurableJoint>();
            joint.connectedBody = HandRig;
            joint.xMotion = ConfigurableJointMotion.Locked;
            joint.yMotion = ConfigurableJointMotion.Locked;
            joint.zMotion = ConfigurableJointMotion.Locked;
            joint.anchor = joint.transform.InverseTransformPoint(hit.point);
            handupdis = Vector3.Distance(hit.point, myCamera.transform.position);
        }
    }

    private void Move(Vector3 pos)
    {
        pos.z = handupdis;
        Vector2 world = myCamera.ScreenToWorldPoint(pos);
        
        HandRig.transform.position = world;
    }
    void Update()
    {

        if (Input.GetMouseButtonDown(0))
        {
            Hand(Input.mousePosition.x,Input.mousePosition.y);
        }
        if (Input.GetMouseButton(0))
        {
            Move(Input.mousePosition);
        }
        if (Input.GetMouseButtonUp(0))
        {
            Destroy(joint);
        }
    }
}

最终效果如下:
Unity使用ConfigurableJoint实现物理拖拽物体
最后,Joint家族里还可以使用其他的Joint来实现,例如SpringJoint,那就带有弹簧效果了,原理都是一样和一个刚体链接起来就可以了。文章来源地址https://www.toymoban.com/news/detail-404670.html

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

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

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

相关文章

  • Unity中鼠标控制3D物体进行拖拽

    拖拽 1 、获取3D物体在世界坐标的位置转换屏幕坐标 2、鼠标在屏幕的坐标与物体在屏幕的坐标Z轴进行拟合 3、获取3D物体与拟合出来的坐标的偏移量 4、通过向量投影得到移动坐标 5、上干货,附带手指控制,手指控制逻辑同鼠标一样 自由拖拽 自由拖拽同上不同的是 获取3D物

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

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

    2024年02月11日
    浏览(91)
  • 使用Unity里的ShaderGraph实现物体边框呼吸灯效果

    提前声明一下,以下效果需要在hdrp项目中进行。 首先创建好我们的正方体: 用来接下来的边框显示。 这里需要创建两个材质球,一个用于显示方块的材质,另一个用于边框的显示。 (Material用于方块材质,OutlineMat用于边框线) 为了更好地突出边框的视觉效果我这里给它加

    2024年04月22日
    浏览(51)
  • Unity 基于URP使用Highlight Plus实现物体高亮

    内容将会持续更新,有错误的地方欢迎指正,谢谢!   Unity 基于URP使用Highlight Plus实现物体高亮       TechX 坚持将创新的科技带给世界! 拥有更好的学习体验 —— 不断努力,不断进步,不断探索 TechX —— 心探索、心进取! 助力快速实现 Highlight Plus 基于URP的物体高亮 为初学

    2024年02月05日
    浏览(37)
  • [Unity] 使用Mathf函数实现平滑移动物体的7种方法

     Unity中要利用Mathf中的函数实现物体的平滑运动,有以下7种方法: Mathf.SmoothDamp、Mathf.Lerp、Mathf.SmoothStep三个方法非常相似,分别使用三个方法移动同一个物体的效果如图所示: 可以看出,三者均是先快后慢,但SmoothDamp方法会有一些卡顿;SmoothStep与Lerp比较起来,Mathf.Smooth

    2024年02月12日
    浏览(51)
  • Unity 使用Final IK实现拟真调整物体IK动画

    演示视频 需求 NPC拿起物体,指定转向放到指定位置,要求动作尽可能自然,贴近真实。 何为IK 谈IK之前先讲一下 正向运动学(forward kinematics) ,正向动力学通俗来说就是 父骨骼带动子骨骼运动 ,Unity父子对象其实已经实现了正向动力学基本功能,当你移动父物体,子物体保

    2024年02月07日
    浏览(42)
  • 【Unity自动寻路】使用Navigation系统实现物体自动寻路绕开障碍物

    知识点流程图 我们在游戏场景中经常会有一些障碍物、墙壁、树木等等,如果我想要让角色或者怪物去墙的另一边,我直接在墙另一边点击左键,我希望角色自动跑过去,但是他不能直接穿透墙,他需要“智能”的绕开障碍物,自动找到可以走的路,自己过去!这就是Unity

    2024年02月03日
    浏览(47)
  • 【Unity实现背包拖拽功能 】

    Unity实现背包拖拽功能 可以实现背包拖拽交换位置、合成 等一系列功能的实现

    2024年02月12日
    浏览(54)
  • unity手指、鼠标滑动实现物体360度旋转、点击按钮实现物体旋转

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

    2024年02月11日
    浏览(64)
  • unity实现鼠标拖拽物品移动

    unity实现物品拖拽,3D创景需要注意的是一个屏幕坐标转换为世界坐标和世界坐标转换屏幕坐标,熟悉他们之间的转化,就没什么难度了 从摄像机发射一条射线,通过射线检测到鼠标点击的物体,将物品的世界坐标转换为屏幕坐标 将鼠标的位置为,鼠标点击的XY轴和物品的

    2024年02月11日
    浏览(74)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包