Nehmen wir an, Sie haben ein Rigidbody
Objekt, das sich bewegt. Dieses Objekt wird über Rigidbody.AddForce
oder Rigidbody.velocity
Force hinzugefügt. Das Objekt kann einen anderen Gegenstand treffen und die Richtung ändern.Vorhersage der Position eines Rigidbody-Objekts in x-Sekunden
Ich weiß über Extrapolation aber in diesem Fall ist es fast unmöglich, eine Formel zu verwenden, um die Position des Objekts in x Sekunden zu erhalten, da das Objekt ein anderes Objekt treffen kann und die Geschwindigkeit/Richtung im Prozess ändern.
Einheit 2017 eingeführt Physics.autoSimulation
und Physics.Simulate
, um dieses Problem zu lösen. Für 2D-Physik ist das Physics2D.autoSimulation
und Physics2D.Simulate
. Alles, was ich getan habe, war zuerst Physics.autoSimulation
zu false gesetzt dann rufen Sie die Physics.Simulate
Funktion.
In meinem Beispiel ich, wo ein Rigidbody
wäre in 4
Sekunden nach der Zugabe von Kraft auf sie, scheint es zu funktionieren gut für kleine Sekunden wie 1
wissen wollte. Das Problem ist, dass wenn ich größere Zahlen wie 5
und höher an die Simulate
Funktion übergebe, ist die vorhergesagte Position nicht genau. Es ist weit weg.
Warum passiert das und wie kann ich es beheben? Dieses Problem ist auf Android-Geräten schlimmer.
Meine aktuelle Unity-Version ist Unity 2017.2.0b5.
Unten ist der Beispielcode, den ich verwende. Das guide
GameObject wird einfach verwendet, um anzuzeigen, wo diese vorhergesagte Position ist.
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;
}
Dank. Das hat gut funktioniert. – Programmer