我有一个由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;
}
}
}
片刻之间,点和框的边缘相互反弹。
但是一段时间后,它们最终被卡在盒子的边缘。
盒子和球以及盒子的壁具有相同的物理材质
具有零摩擦和1的反弹度。
为什么它们会粘在墙上,我该如何阻止它发生?
UPDATE如果我将单个分子放入带有以下脚本的盒子中,它会立即粘在墙上。
[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);
}
}
Unity3D具有速度阈值。速度低于此阈值的对象不会反弹等。
解决方案是转到编辑>项目设置>物理2D,并将“速度阈值”设置得较低。
编辑-实际解决方案:
因此,我正在阅读一些有关积分技术的文章,这让我大吃一惊:您正在失去的精力很可能是由于几种近似技术的复合所导致的数值误差。
我猜想,连续碰撞检测算法主要归咎于浮点错误累积,但也可能来自数值积分技术。
您要实现的是弹性碰撞,这意味着它既满足能量守恒,又满足动量守恒。诀窍将是为您添加脚本到每个对象,以通过随时间增加纠错速度来保留系统的能量。无论您是否实际使用能量路线,都取决于您自己,有多种方法可以跟踪和修改能量,从而改变速度。在我看来,动量将是最容易追踪的。您要实现的是弹性碰撞,这意味着它可以满足保护要求即
使分量保留动能或动量的标量(可能会产生相同的结果)
当您用速度初始化所有粒子时,请确保将起始动量保存在粒子脚本中。为了简单起见,我将保存标量,所以只需使用速度的长度
每帧,在更新事件中,检查刚体的速度。找到动量的变化或能量的变化,并添加-差并将其应用于对象。
我怀疑您也必须处理碰撞事件,特别是如果您对每个对象使用完全相同的质量。这是一个示例的链接,其中有人使用能量守恒https://answers.unity.com/questions/168393/frictionless-physics.html
纠正了统一的无摩擦物理。由于低的接触偏移,对撞机可能会相互卡住,请转到edit-project settings-physics2d并稍微增加默认的接触偏移,例如0.12,这对我有用。
欢呼声