2017-08-03 60 views
1

假設您有一個可移動的Rigidbody對象。強制通過Rigidbody.AddForceRigidbody.velocity添加到此對象。對象可以滾動另一個對象並改變方向。預測x秒內剛體對象的位置

我知道Extrapolation但在這種情況下,它幾乎是不可能使用一些公式來獲得X秒的對象的位置,因爲對象可以擊中另一個對象並在過程中改變速度/方向。

Unity 2017推出了Physics.autoSimulationPhysics.Simulate來解決這個問題。對於2D物理,那是Physics2D.autoSimulationPhysics2D.Simulate。我所做的只是第一次將Physics.autoSimulation設置爲false,然後調用Physics.Simulate函數。


在我的例子,我想知道一個Rigidbody將是4秒加入力之後,它似乎做工精細的微小秒像1。問題是,當我通過像5及以上的更大數字,Simulate函數,預測的位置是而不是準確。它的方式是關閉的。

爲什麼會發生這種情況,我該如何解決? Android設備上的這個問題更嚴重。

我目前的Unity版本是Unity 2017.2.0b5

下面是我使用的示例代碼。遊戲對象僅用於顯示/顯示預測位置的位置。

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<Rigidbody>(); 

    //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; 
} 

回答

2

你甚至很幸運1的價值工作。您不應該通過0.03以上的任何值到Physics.SimulatePhysics2D.Simulate函數。

當值大於0.03時,您必須將它分解成小塊,然後在循環中使用Simulate函數。減少x時間,同時檢查它是否仍然大於或等於Time.fixedDeltaTime應該這樣做。

更換

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; 
} 
+0

感謝。這工作得很好。 – Programmer