为什么对象在 Unity 中会卡在一起?

Why do objects get stuck together in Unity?

我有一个包含 4 个精灵的 2D 场景,每个精灵都有一个盒子碰撞器。

然后我有一个预制件,它只是一个带有 2D 圆形碰撞器的圆形精灵。

最后,我有一个名为 Atmosphere 的脚本附加到我的主摄像头,它将用大量预制件实例填充盒子,并为它们提供随机方向的速度。

使用 UnityEngine;

public class Atmosphere : MonoBehaviour
{
    public GameObject Molecule;
    void Start()
    {
        float x = -4.5f;
        while (x < 4.5f)
        {
            float y = -4.5f;
            while (y < 4.5f)
            {
                var inst = GameObject.Instantiate(Molecule);
                inst.transform.position = new Vector3(x, y, 0);
                var rb = inst.GetComponent<Rigidbody2D>();
                float xForce = Random.value * 2f - 1f;
                float yForce = Random.value * 2f - 1f;
                rb.AddForce(new Vector2(xForce, yForce) * 100f);
                y += 0.5f;
            }
            x += 0.5f;
        }
    }
}

有一段时间,这些点相互弹跳,并在盒子的边缘弹跳。

但过了一会儿,它们最终卡在了盒子的边缘。

盒子和球以及盒子壁具有相同的物理特性material

摩擦力为零,弹性为 1。

为什么它们会粘在墙上,我怎样才能阻止它发生?

Download Unity 3D demo

更新 如果我将一个分子放入附有以下脚本的盒子中,它会立即粘在墙上。

[RequireComponent(typeof(Rigidbody2D))]
public class Molecule : MonoBehaviour
{
    Rigidbody2D RigidBody2D;

    void Start()
    {
        transform.position = new Vector3(0, 1, 0);
        RigidBody2D = GetComponent<Rigidbody2D>();
        float xForce = Random.value * 2f - 1f;
        float yForce = Random.value * 2f - 1f;
        RigidBody2D.AddForce(new Vector2(-.25f, -0.25f) * 100f);
    }
}

编辑 - 真正的解决方案:

所以我正在阅读一些关于积分技术的资料,这让我震惊:你失去的能量很可能来自于多种近似技术复合产生的数值不准确。

我猜主要是连续碰撞检测算法的罪魁祸首,浮点误差累积,但也可能来自数值积分技术。

你要实现的是弹性碰撞,也就是说既满足动量守恒又满足能量守恒。诀窍是为每个对象添加一个脚本,通过随时间增加纠错速度来保持系统的能量。您是否实际使用能量路线取决于您,有多种方法可以跟踪和修改导致速度变化的能量。在我看来,动量将是最容易追踪的。您要实现的是弹性碰撞,这意味着它满足守恒 即

  1. 制作一个保留动能或动量标量的组件(它可能会产生相同的结果)

  2. 当您用速度初始化所有粒子时,请确保在粒子脚本中保存起始动量。为了简单起见,我会保留标量,所以只需使用速度的长度

  3. 每一帧,在更新事件中检查刚体的速度。找到动量的变化或能量的变化,并添加 -difference 并将其应用于对象。

我怀疑您是否也必须处理碰撞事件,尤其是当您对每个对象使用完全相同的质量时。这是一个 link 示例,其中有人使用能量守恒 https://answers.unity.com/questions/168393/frictionless-physics.html

修正了 unity 的无摩擦物理学

Unity3D 有一个速度阈值。速度低于此阈值的物体不会反弹等

解决方案是转至 编辑 > 项目设置 > 物理 2D 并将速度阈值设置得较低。

碰撞器可能由于低接触偏移而相互卡住,转到编辑-项目设置-physics2d 并稍微增加默认接触偏移,例如 0.12,这对我有用。

干杯