在具有统一初始脉冲的抛物线路径上移动 2D 物理体
Posted
技术标签:
【中文标题】在具有统一初始脉冲的抛物线路径上移动 2D 物理体【英文标题】:Moving a 2D physics body on a parabolic path with initial impulse in unity 【发布时间】:2017-03-14 17:08:26 【问题描述】:我有什么:
Unity 5 2D 中的弹丸,受重力影响,我想在抛物线路径上以初始冲量从 A 点移动到 B 点
我所知道的:
随机起始位置的二维坐标 (A) 随机目标位置的二维坐标 (B) 我希望身体在之后到达目标位置的时间 (X)我想知道的:
我必须一次向身体施加的初始脉冲(如统一施加力和 forcemode 脉冲)以使其在 X 时间后到达所需的位置 B。注意事项:
这是一个使用 Unity 2D 物理的 2D 世界 A 和 B 两个位置是完全随机的,可能高度相同,也可能不同(y 坐标) 我只想在产生射弹时应用一次脉冲 除了重力之外,弹丸没有任何其他影响他的力(对于当前的问题,我们假设它总是向下指向 9.8 等)这是我想要的(坏)图:D
先谢谢各位了!
【问题讨论】:
【参考方案1】:让我们解决一些简单的问题。我们的目标是找到粒子的初始速度,而不是“脉冲”,因为我们将通过这种方式实现更好的控制。
首先,考虑我们如何在没有 Unity 物理的情况下解决这个问题。作为时间函数的粒子位置取决于其初始位置、速度和加速度。无论您有多少维度,都适用相同的方程式。这个方程是:
current_position = 1/2 * acceleration * time^2 + velocity * time + starting_position
让current_position
是我们想要的目的地,time
是你选择的旅行时间,starting_position
是粒子的起始位置。
在 x 维度上,没有加速度。让X_0
是我们的起始 X 位置,X_1
是我们的目的地,T
是我们想要到达该目的地所花费的时间。我们想找到v_x
,或 x 维度上的速度。为了便于解释,我将所有常量标记为大写,变量标记为小写。
X_1 = v_x*T + X_0
v_x = (X_1-X_0)/T
在 y 维度,我们有某种重力。所以让我们把它作为我们的加速:
Y_1 = 0.5*G*T*T + v_y*T + Y_0
v_y = (Y_1 - Y_0 - 0.5*G*T*T)/T
现在您有了v_x
和v_y
,只需设置速度:
rigidbody2d.velocity = new Vector2(v_x, v_y);
由于不同的物体有不同的质量,你不想尝试计算冲量。只需在生成对象时将速度设置为帧中所需的速度即可。
这与您可能在 Internet 其他地方找到的建议相反,但请先尝试,然后再进行更复杂的操作。
一些重要说明:
Unity 中的物理处理不稳定:您可能会在不同的平台上得到不同的结果,尤其是在不同的移动设备之间。如果存在性能压力,则物理评估可能会减少,从而导致结果不正确。这通常不是 2D 物理的问题。 您可能会遇到重力比例问题,具体取决于您的版本和其他设置。【讨论】:
【参考方案2】:仅受重力影响的弹丸位置公式如下:
x = x0 + v_x0*t
y = y0 + v_y0*t + 0.5*g*t^2
所以,要知道起始速度,通过一些基本的计算:
v_x0 = (x-x0)/t
v_y0 = (y-y0)/t + 0.5*g*t^2/t = (y-y0)/t - 4.9*t
现在,为了使用AddForce
添加这个起始速度,我们可以使用ForceMode.VelocityChange
,但是这种模式只适用于 3D 刚体,所以我们需要使用ForceMode.Impulse
并将力乘以物体的质量:
RigidBody2D rigid = GetComponent<RigidBody2D>();
rigid.AddForce(new Vector2 (v_x0, v_y0) * rigid.mass, ForceMode2D.Impulse);
就是这样。
当然你可以直接设置刚体的速度,而不是使用AddForce
。
【讨论】:
以上是关于在具有统一初始脉冲的抛物线路径上移动 2D 物理体的主要内容,如果未能解决你的问题,请参考以下文章
如何显示抛物线运动以及如何在 Cocos2D 中找到 Sprite 的最终位置 [关闭]