Unity3D Physics Rigidbody不会检测到碰撞

时间:2018-03-02 06:02:48

标签: c# unity3d

我正在建立一个团结的简单游戏,其中包括两个相互冲压的玩家。玩家可以在舞台上移动并单击按钮在他们面前打卡,目标是将其他玩家从舞台上击倒。

我从this link获得了一个打孔脚本,但是它的编写方式是在打孔动画期间打孔不与其他Rigidbodies交互,只有当打孔功能没有时才会检测到碰撞活性。建议与我使用Rigidbody.MovePosition()的其他Rigidbodies合作。我尝试用MovePosition()实现它,但最终删除了打孔动画并让我离解决方案更远。

这是打孔脚本

IEnumerator Punch(float time, float distance, Vector3 direction)
{
    punching = true;
    var timer = 0.0f;
    var orgPos = transform.position;
    direction.Normalize();
    while (timer <= time) {
        transform.position = orgPos + (Mathf.Sin(timer / time * Mathf.PI) + 1.0f) * direction;
        yield return null;
        timer += Time.deltaTime;
    }
    transform.position = orgPos;
    punching = false;
}

MovePosition()

IEnumerator Punch(float time, float distance, Vector3 direction)
{
    punching = true;
    var timer = 0.0f;
    var orgPos = transform.position;
    direction.Normalize();
    rb.MovePosition(orgPos + direction);
    yield return null;
    rb.MovePosition(orgPos);
    punching = false;
}

我100%确定我正确设置了玩家的物理组件,唯一的问题是当玩家互相冲击时没有碰撞检测。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

TL; DR :获取第一个脚本并将transform.position = ...;更改为rigidbody.MovePosition (...);

这里有两种可能性:a)您的刚体和目标未正确配置(例如,一个物体是静态物体),或b)您的刚体实际上从未相交过。

确保物理实际正确设置

如果您(或其他读者)需要验证其物理刚体是否已正确配置,请检查:

  1. 碰撞游戏对象在检查器的右上角也没有标记为静态,
  2. RigidBody组件未标记为Kinematic。
  3. 最后,验证GameObject是否有正确配置的碰撞器(通常是Box Collider,Sphere Collider或Capsule Collider)。
  4. 确定刚体是否实际相交

    第二个问题仅仅取决于对象&#39;改变空间内的位置。当然,如果您使用物理模拟刚体对象,则不应该直接指定这些位置,而是使用Rigidbody的方法,这就是为什么有使用{{{ 1}}。

    稍微备份并确保未来的任何读者都在同一页面上,这些Punch脚本本身与刚体的碰撞检测无关,而且实际上只是用于改变GameObject的位置相对于它的父母。换句话说,剧本的第一次迭代只是在短时间内向前和向后推动拳头。这里的问题是它直接修改了转换,这对于非运动刚体来说是不明智的。

    第二个脚本尝试使用变换来纠正位置的直接分配的问题在于它立即向前推动手(直到第一个Rigidbody.MovePosition ()中的点),然后缩回对象在协同程序运行的下一帧上。

    相反,请使用第一个脚本并将其从使用yield return null更改为Transform.position = ...;。这样做应该会恢复拳头的动画运动。此外,如果您还没有,在rigidbody.MovePosition (...);中,您应该获得对刚体的引用,然后将其存储在成员变量中以供在此处使用。

    最后,请注意,如果插值属性设置为true,则MovePosition仅插入移动,默认情况下,插值为false,但字符控制器除外。即便如此,您的第二个协程也不足以进行插值。

    最终的脚本可能如下所示:

    void Awake ()