我很难过,因为我无法理解这个问题:
我正在尝试使用维基百科上的公式让一个物体围绕行星在圆形轨道上移动,这里的任何方式都是我的代码:
public void circularOrbit(Collider2D col,float planetMass){
mPlanet = planetMass;
dist = new Vector2 (col.gameObject.transform.position.x - gameObject.transform.position.x, col.gameObject.transform.position.y - gameObject.transform.position.y);
r = dist.magnitude;
print (r);
tdist = new Vector2 (-dist.y, dist.x).normalized; // 2D vector prependicular to the dist vector .
float speed = Mathf.Sqrt ( G*mPlanet / r) ; // Calculate the velocity .
print (speed);
rigidbody2D.velocity = tdist * speed;
}
2D对撞机col
是行星轨道的对撞机,当我的物体碰到这个对撞机时,它会根据我所做的计算开始以圆形方式移动。
一切都在一个固定的更新中有一些条件(与这个主题没有真正关系),我面临的问题是我的距离大小不断改变每一帧,我需要它保持不变!
这会导致问题,因为速度会发生变化,而对于我需要修复的其他脚本。
以下是r
距离幅度的一些值:
4.602833
4.602901
4.603098
变化很小,但它对我的游戏玩法影响太大。
那么请解释一下为什么会这样?
谢谢。
答案 0 :(得分:0)
物理引擎对固定更新执行更新。在这些更新之间,重力不会作用于对象。因此,它在一条直线段中移动,该直线段开始与您想要的圆相切,但在固定更新周期结束时,距离略有增加,因为线段与圆不同。结果是您可能会看到比舍入错误大得多的错误。
此错误是线性的。如果您有两倍的更新,或者将速度和重力降低两倍,则每一步的误差将缩小大约四倍,但由于每个轨道的更新数量是原来的两倍,因此额外的距离每个轨道将减少两倍。
如果你有一个复杂的模拟物体在椭圆和多个重要的重力源中移动,那么我建议使用像leapfrog integration这样节省能量的方法,或者使用高阶Runge-Kutta方法,这是通常非常准确,以至于您不会注意到错误。但是,你已经施加了一个圆形轨道而不是让物理引擎计算轨道。因此,只需覆盖物理引擎的计算,并强制对象位于您应知道的轨道上。一种方法是将旧位移从行星的中心旋转一个角度,即(Time.deltaTime / period)* 2pi弧度。这并不完美,因为可能会累积一些舍入误差。另一种可能性是跟踪原始位置和原始时间,并根据当前时间和原始时间之间的差异计算角度。
另一种应该工作的方法是记住半径应该是什么,并将行星中心的位移重新规范化,使其大小等于记忆半径。