2017-08-03 22 views
1

移動するオブジェクトがRigidbodyであるとします。このオブジェクトには、forceがRigidbody.AddForceまたはRigidbody.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です。

以下は、私が使用しているサンプルコードです。 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<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.SimulateまたはPhysics2D.Simulate関数に渡すべきではありません。

値が0.03より大きい場合は、それを分割してループ内でSimulate関数を使用する必要があります。 xの時間を減らして、まだそれ以上であるかどうかを確認しながら、Time.fixedDeltaTimeにする必要があります。

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

ありがとう:

は、次のようになります

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

あなたの新しい完全なpredictRigidBodyPosInTime機能を

Physics.Simulate(timeInSec); 

を交換してください。これはうまくいった。 – Programmer

関連する問題