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