RigidBody2D AddForce 不添加加速度

RigidBody2D AddForce Not Adding Acceleration

我正在尝试使用 AddForce 为带有 RigidBody2D 组件的 object 添加加速度,但它似乎只是添加固定速度。

这里是 RigidBody2D 设置:

为了测试,我修改了 Update 函数以允许我添加力并定期报告 object 的速度:

void Update()
{
    time += Time.deltaTime;
    if (time > 0.5)
    {
        Debug.Log("Velocity magnitude = " + rigidbody2D.velocity.magnitude);
        time = 0;
    }

    if (Input.GetKeyDown(KeyCode.Q))
    {
        rigidbody2D.AddForce(Vector2.right);
    }
}

我看到的是,每按一次Q,速度幅度都会增加一个固定的0.02。

即首先它根本不移动并且速度为 0,然后在按下 Q 之后速度幅度变为 0.02 并保持在 0.02 而 object 缓慢地向右移动。再次按 Q 将其增加到 0.04,然后再按一次将其增加到 0.06 依此类推。

这些是两天前的结果。我今天又做了一次实验,得到了不同的速度增量,但其他方面的行为相同。

当我添加一个力时,速度变化

如果我将一个大小为 1 的力加到质量为 1 的静止 object 上,那么它的速度将在每个时间单位(我认为这里是秒)增加 1。

而是保持不变。

使用 ForceMode2D.Impulse 将速度增量从 0.02 增加到 1,但行为保持不变 - 没有加速度,只有 one-time 速度增量。

我做错了什么?


我尝试寻找类似的帖子和一般问题,但我发现的唯一问题要么是无关紧要的,要么是问相反的问题(如何阻止加速发生)。

如有任何帮助,我们将不胜感激。

Unity版本为2019.1.1f1.

我认为这不会为物体增加足够的力使其运动。通常,您需要将方向乘以 "force" 倍数。尝试像 rigidbody2D.AddForce(Vector2.right * 1000); 这样的东西。也就是说,故意地,可能用力太大了,但至少你会知道它在移动。

TL;DR

你做错的是你期望从应用力函数中得到错误的物理行为。该函数按照它说的做,它施加力。它会立即改变物体的速度。二维物体的力模式只告诉引擎是否考虑物体的质量。

问题是 Unity 使用的命名,AddForce 不 "add" 力,它只是为单个帧应用力。在接下来的帧中,所有力再次为零。如果你想保持力,只需在你的脚本中创建你自己的向量,修改它,然后使用 AddForce 将它应用到对象的每一帧。


你好吗?

我已经创建了一个示例项目来重现您的问题,但我无法重现您所说的保持固定的速度。我不确定你是如何设置场景的,所以我做了一些假设。您可能禁用了物体上的重力或摩擦力,因为您报告速度增加了。

另一方面,加速度是施加的恒定力,想一想。如果你的车静止不动,你推动它一小段时间,它就会移动然后停下来。另一方面,如果你继续推动,增加越来越多的力,汽车就会移动得越来越快。现在想想你的环境,你有一个无摩擦的物体。每次按下 Q 时,都会向其添加一个小的力。它向右移动的速度稍快但速度恒定(没有力改变它的速度)。

这是您想要执行的操作。不要只在你按下 Q 的帧中添加力,而是在你按下 Q 的同时添加。这就是你想要做的:

private void FixedUpdate()
{
    time += Time.deltaTime;
    if (time > 0.5)
    {
        Debug.Log("Velocity magnitude = " + rigidbody2D.velocity.magnitude);
        time = 0;
    }

    if (Input.GetKey(KeyCode.Q))
    {
        rigidbody2D.AddForce(speedMultiplier * Time.fixedTime * Vector2.right, ForceMode2D.Force);
    }
}

另一个问题是 Unity 使用的命名,AddForce 不 "add" 力,它只是为单个帧应用力。在接下来的帧中,所有力再次为零。如果你想保持力,只需在你的脚本中创建你自己的向量,修改它,然后使用 AddForce 将它应用到对象的每一帧。

另外,看到我把Update改成了FixedUpdate了吗?在 Unity 中,建议您改为应用该方法中的所有物理变化。更新尽可能多地运行(如果可能,每帧一次),固定更新仅在物理线程完成后运行。这意味着您不会花费 CPU 时间告诉对象在每一帧移动,而是在等待物理同步。