【问题标题】:Unity 3D OnMouseDrag collisionUnity 3D OnMouseDrag 碰撞
【发布时间】:2016-03-31 16:21:42
【问题描述】:

我正在尝试制作一款游戏,您可以拖动不同类型的球体并将它们组合在一起形成一个图形(没有任何重力)。为了拖动我使用这个脚本的对象:

using UnityEngine;
using System.Collections;

public class Test : MonoBehaviour {

    void OnMouseDrag()
    {
        float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
        transform.position = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance_to_screen ));

    }

}

当我将两个球体拖到一起时,它们会互相穿过。我在物体上添加了一个刚体,用它尝试了很多不同的东西,但似乎没有任何效果。他们似乎总是互相反弹,或者他们根本不碰撞。有什么解决办法吗?想象这就像一个人跑到墙上。这个人没有从墙上反弹,他只是停止移动。

【问题讨论】:

  • 将刚体更改为动力学?
  • @ŁukaszMotyczka 我试过了,它们全都漂浮在空中。

标签: c# unity3d game-physics


【解决方案1】:

出现一些奇怪行为(对象相互剪切/忽略)的原因是您直接设置了transform.position,而不是操纵对象的Rigidbody 组件。使用Rigidbody.MovePosition() 还可以在定位对象时考虑物理因素。

现在,看到物体相互反弹并不是一种异常的物理行为 - 这是因为当物体相互夹住时(就像它们经常对您的代码所做的那样),它们会对彼此施加排斥力(有点像牛顿第三定律)。如果您想在它们碰撞时立即冻结它们,请尝试在 OnCollisionEnter() 事件中设置 Rigidbody.isKinematic = true

将所有这些放在一起,您的课程可能如下所示:

public class Test : MonoBehaviour {

    Rigidbody rb;

    void Start()
    {
        // Store reference to attached Rigidbody
        rb = GetComponent<Rigidbody>();
    }

    void OnMouseDrag()
    {
        float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;

        // Move by Rigidbody rather than transform directly
        rb.MovePosition(Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance_to_screen )));
    }

    void OnCollisionEnter(Collision col)
    {
        // Freeze on collision
        rb.isKinematic = true;
    }
}

希望这会有所帮助!如果您有任何问题,请告诉我。

【讨论】:

  • 非常感谢,我回家试试这个。
  • 拖动对象完美无缺,就像以前一样。只有碰撞根本不起作用。编辑:没有什么真正改变。 EDIT2:在我碰撞它们的第一秒,它起作用了。在那之后,他们立即进入了对方
  • @BelgianWizard 您是否打算在初始碰撞后完全冻结对象(即忽略所有物理和任何进一步的鼠标拖动)?还是您仍然希望它停止后仍可拖动? (如果是后者,您的实现可能必须进行重大更改。)
  • 我们有点让它工作,但我们仍然有一个小问题。你有时间在 Skype 等第三方软件中聊天吗?我可以私下发给你我的用户名。编辑:我如何 PM?
  • @BelgianWizard 抱歉,我目前无法访问类似的内容。不过,我们可以使用 StackOverflow 聊天室。 (本网站没有 PM 功能。)
【解决方案2】:

当以非增量方式直接给出位置变量坐标时,对象会在下一个位置“逐步”存在,从而欺骗碰撞系统。

您必须通过让某种其他系统以增量方式移动对象来对其进行编码:

而不是像这样直接移动对象:

位置 =

position = lerp(oldPosition,new position,Time.deltaTime)

【讨论】:

  • 您可以编辑您的帖子。不要在评论区继续你的回答。
猜你喜欢
  • 1970-01-01
  • 2017-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多