简体   繁体   中英

How does Spaceflight simulator predict flight-paths?

I am trying to make a game with Unity that uses rockets that are in orbit and can transition to different planets, but I need to predict the rocket path in real-time, depending on the current velocity/direction of the rocket allot like spaceflight simulator does.

I have managed to get realistic physics and orbits when adding gravitational forces to a rigidBody:

    var sateliteCords = Satelite.transform.position;
    var planetCords = gameObject.transform.position;
    var distance = sateliteCords - planetCords;
    distanceFromSatelite = Vector3.Distance(Satelite.transform.position, gameObject.transform.position);
    F = (Gravity * Mass) / Mathf.Pow(distanceFromSatelite,2);
    forces = (distance / Mathf.Sqrt(Mathf.Pow(distance.x, 2)+ Mathf.Pow(distance.y, 2)+ Mathf.Pow(distance.z, 2))) * -F;
    Satelite.GetComponent<Rigidbody>().AddForce(forces * Time.deltaTime, ForceMode.Force);

but I don't know how to predict future points in time to give me the orbit shape.

I have tried "speeding up the simulation" with Time.timeScale = 50; but it isn't fast enough. I read somewhere that I need a copy of the solar system running independently form the unity updates, and calculate the rocket trajectory from there but I don't know how to approach that.

I'm a bit of a noob when it comes to physics simulations so can one of you geniuses please help?

Here's what your code is actually doing:

var sateliteCords = Satelite.transform.position;
var planetCords = gameObject.transform.position;
var distance = sateliteCords - planetCords;
distanceFromSatelite = distance.magnitude;

F = (Gravity * Mass) / Mathf.Pow(distanceFromSatelite,2);
forces = distance / distanceFromSatellite * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces * Time.deltaTime, ForceMode.Force);

You can further reduce it by doing:

var distance = sateliteCords - planetCords;
distanceSqrMag = distance.sqrMagnitude;

F = (Gravity * Mass) / distanceSqrMag;
forces = distance.normalized * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces * Time.deltaTime, ForceMode.Force);

Now that the code is much simpler, I can find a crucial mistake. ForceMode.Force already multiplies the Force by Time.deltaTime. What you want here is to switch to ForceMode.Impulse, or remove the deltaTime.

F = (Gravity * Mass) / distanceSqrMag;
forces = distance.normalized * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces, ForceMode.Force);

Or better yet, assuming Mass is the mass of the satellite, and gravity is not a general constant, but just the local gravity of your planet. ForceMode.Force divides the force by the mass of the rigidbody it is applied on.

F = Gravity / distanceSqrMag;
forces = distance.normalized * -F;
Satelite.GetComponent<Rigidbody>().AddForce(forces, ForceMode.Acceleration);

Now that's all out the way, you can do a very simple approximation by doing something like

var currentPos = _rigidBody.position;
var prevPos = currentPos;
var currentVelocity = _rigidBody.velocity;
var planetCords = gameObject.transform.position;

for (int i = 0; i < stepCount; i++)
{
    var distance = planetCords - currentPos;

    var forceMag = Gravity / distance.sqrMagnitude;
    forces = distance.normalized * forceMag;
    currentVelocity  += forces * Time.fixedDeltaTime;

    currentPos += currentVelocity * Time.fixedDeltaTime;

    //Replace by a TrailRenderer you reset each frame
    Debug.DrawLine(prevPos, currentPos, Color.Red, Time.deltaTime);
    prevPos = currentPos;
}

Note that this code is untested, I probably made a mistake here or there, but that's the gist of it.

Don't worry about getting any difference in trajectory, this is exactly what unity does to predict positions. No need for fancy calculations when you got all the computing power you need.

If you want more than one-body gravity simulation, it's simple. Either apply the gravity of all planets, or simply the gravity of the closest planet taking its mass into account. I recommend the former if you have less than a dozen planets.

You don't need conics, or advanced math, or any of that. You're not kerbal space program. Sometime brute force is the best solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM