以x秒为单位预测刚体对象的位置

假设你有一个移动的Rigidbody对象。 Force通过Rigidbody.AddForceRigidbody.velocity添加到此Object。 对象可以滚动命中另一个对象并改变方向。

我知道外推,但在这种情况下,几乎不可能使用一些公式来获得x秒内物体的位置,因为物体可以击中另一个物体并改变过程中的速度/方向。

Unity 2017引入了Physics.autoSimulationPhysics.Simulate来解决这个问题。 对于2D物理学,即Physics2D.autoSimulationPhysics2D.Simulate 。 我所做的只是将Physics.autoSimulation设置为false然后调用Physics.Simulate函数。


在我的例子中,我想知道在为它添加力之后4秒内Rigidbody会在哪里,它似乎在1秒的小秒内工作正常。 问题是,当我传递大于5和更高的数字时,对于Simulate函数,预测位置准确。 离开的路还很远。

为什么会发生这种情况,我该如何解决? Android设备上的这个问题更严重。

我目前的Unity版本是Unity 2017.2.0b5

下面是我正在使用的示例代码。 guide GameObject仅用于显示/显示预测位置的位置。

 public GameObject bulletPrefab; public float forceSpeed = 50; public GameObject guide; // Use this for initialization IEnumerator Start() { //Disable Physics AutoSimulation Physics.autoSimulation = false; //Wait for game to start in the editor before moving on(NOT NECESSARY) yield return new WaitForSeconds(1); //Instantiate Bullet GameObject obj = Instantiate(bulletPrefab); Rigidbody bulletRigidbody = obj.GetComponent(); //Calcuate force speed. (Shoot towards the x + axis) Vector3 tempForce = bulletRigidbody.transform.right; tempForce.y += 0.4f; Vector3 force = tempForce * forceSpeed; //Addforce to the Bullet bulletRigidbody.AddForce(force, ForceMode.Impulse); //yield break; //Predict where the Rigidbody will be in 4 seconds Vector3 futurePos = predictRigidBodyPosInTime(bulletRigidbody, 4f);//1.3f //Show us where that would be guide.transform.position = futurePos; } Vector3 predictRigidBodyPosInTime(Rigidbody sourceRigidbody, float timeInSec) { //Get current Position Vector3 defaultPos = sourceRigidbody.position; Debug.Log("Predicting Future Pos from::: x " + defaultPos.x + " y:" + defaultPos.y + " z:" + defaultPos.z); //Simulate where it will be in x seconds Physics.Simulate(timeInSec); //Get future position Vector3 futurePos = sourceRigidbody.position; Debug.Log("DONE Predicting Future Pos::: x " + futurePos.x + " y:" + futurePos.y + " z:" + futurePos.z); //Re-enable Physics AutoSimulation and Reset position Physics.autoSimulation = true; sourceRigidbody.velocity = Vector3.zero; sourceRigidbody.useGravity = false; sourceRigidbody.position = defaultPos; return futurePos; } 

你甚至很幸运, 1的价值在所有人都有效。 您不应将高于0.03任何值传递给Physics.SimulatePhysics2D.Simulate函数。

当值大于0.03 ,您必须将其分成几部分,然后在循环中使用Simulate函数。 在检查它是否仍然更多或等于Time.fixedDeltaTime时减少x时间应该这样做。

更换

 Physics.Simulate(timeInSec); 

 while (timeInSec >= Time.fixedDeltaTime) { timeInSec -= Time.fixedDeltaTime; Physics.Simulate(Time.fixedDeltaTime); } 

您的新完整predictRigidBodyPosInTime函数应如下所示:

 Vector3 predictRigidBodyPosInTime(Rigidbody sourceRigidbody, float timeInSec) { //Get current Position Vector3 defaultPos = sourceRigidbody.position; Debug.Log("Predicting Future Pos from::: x " + defaultPos.x + " y:" + defaultPos.y + " z:" + defaultPos.z); //Simulate where it will be in x seconds while (timeInSec >= Time.fixedDeltaTime) { timeInSec -= Time.fixedDeltaTime; Physics.Simulate(Time.fixedDeltaTime); } //Get future position Vector3 futurePos = sourceRigidbody.position; Debug.Log("DONE Predicting Future Pos::: x " + futurePos.x + " y:" + futurePos.y + " z:" + futurePos.z); //Re-enable Physics AutoSimulation and Reset position Physics.autoSimulation = true; sourceRigidbody.velocity = Vector3.zero; sourceRigidbody.useGravity = false; sourceRigidbody.position = defaultPos; return futurePos; }