Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Gravity simulation not accurate

Discussion in 'Physics' started by BlackMoss, Aug 14, 2018.

Thread Status:
Not open for further replies.
  1. BlackMoss

    BlackMoss

    Joined:
    Mar 26, 2017
    Posts:
    5
    Hello everyone

    I have been working on a project which will accurately simulate the gravitational interactions between bodies using Newton's law of universal gravitation. To make sure it is working, I have created an approximation of the Earth-Moon system to see if the orbital period of the moon is the same as it is in real life. The problem is that the moon goes way too fast but in more or less the correct orbit. It's as if the time scale was a lot faster. Instead of having an orbital period of 27 days (2332800 s) it goes over 800 times faster. The actual timescale is set to 1, so if all my math is right, it should be moving almost exactly the same as the moon.
    To make the scale and distances easier to handle I have made all the distances 100000 times smaller (the distance between the Earth and Moon is 3844 m instead of 384400000 m), and to make up for this change I have made the gravitational constant ten times smaller because the distance is squared, so 100000^2 = 10^10. You can see all of this in the code below. And as for the masses of each object, I have made a separate variable inside the script attached to each object which can handle the enormous masses of the earth and moon, and have left the rigidbody mass of each attractor as 1 and have left the body to attract's mass out of the equation. I'm sorry if this is really confusing.

    I don't know if the problem is with my math or with the way I'm applying forces or something else. Thank you for any help

    Code (CSharp):
    1. public class Attractor : MonoBehaviour {
    2.  
    3.     public Rigidbody rb;
    4.     public Vector3 startVelocity;
    5.     const double G = 0.000000000000000000006674; // Gravitational constant adapted proportionally to distances and scale (normal value = 6.674*10^-11 = 0.0000000000674)
    6.     public static List<Attractor> Attractors;
    7.     public double mass;
    8.  
    9.     void FixedUpdate () {
    10.         foreach (Attractor attractor in Attractors) {
    11.             if (attractor != this) {
    12.                 Attract (attractor);
    13.             }
    14.         }
    15.     }
    16.  
    17.     void OnEnable () {
    18.  
    19.         rb = GetComponent<Rigidbody>();
    20.  
    21.         rb.velocity = startVelocity;
    22.  
    23.  
    24.         if (Attractors == null) {
    25.             Attractors = new List<Attractor> ();
    26.         }
    27.         Attractors.Add (this);
    28.     }
    29.  
    30.     void OnDisable () {
    31.         Attractors.Remove (this);
    32.     }
    33.  
    34.     void Attract(Attractor bodyToAttract) {
    35.  
    36.         Rigidbody rbToAttract = bodyToAttract.rb;
    37.  
    38.         Vector3 direction = rb.position - rbToAttract.position;
    39.         float distance = direction.magnitude;
    40.  
    41.         Debug.Log(distance);
    42.  
    43.         if (distance == 0)
    44.             return;
    45.  
    46.         double forceMagnitude = G * mass / Mathf.Pow (distance, 2);  // I don't need to multiply by mass on top because when you use rb.AddForce it uses the mass of the rb which is 1, If I did add the actual mass variable of the other body it would add a force way too large
    47.  
    48.         Vector3 force = direction.normalized * (float)forceMagnitude;
    49.         rbToAttract.AddForce (force, ForceMode.Force);
    50.  
    51.  
    52.     }
    53. }
     
  2. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    I would try using the other mass in the formula and use the Impulse force mode to see if it's the problem.

    Looks like it should work, i have a little gravity demo back home i'll pop up the codes when ill get back
     
  3. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,731
    I think you have rounding point issue.
    What is you distance? I assume you keep it far below 10k units.
    Further you go, bigger floating point error you may have.
     
  4. BlackMoss

    BlackMoss

    Joined:
    Mar 26, 2017
    Posts:
    5
    Do you mean the rigidbody mass? I'm not using that because of it's limited accepted values.

    Yes. It's 3844. I don't think a rounding error could cause such a deviation in speed, though.
     
  5. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,731
    I suggest try something with more resealable values at first.
    Check if anything with gravity of 9.81 behaves accurately.
    Then move it further away (or scale), test again and so forth.
    Until you reach you current G. If you start seeing issues along the way, you probably will a bottle neck.
    Then different approach you will need to find, to "trick" real physics.
     
  6. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    I'm talking about the forceMagnitude calculation, use the mass your storing for the wanted force, but try using it in the calculation and using the impulse force mode
    Code (CSharp):
    1. forceMagnitude = G * (myMass * otherMass) / Mathf.Pow(distance, 2);
    2.  
    on second thought this will ignor inertia i think..

    maybe use the rigid body mass instead of you own variable and scaling the whole thing down by some factor?
     
  7. Nest_g

    Nest_g

    Joined:
    Jun 18, 2019
    Posts:
    151
    I am making some physics test in Unity 2003 and is a surprise the inaccurate that gravity works, in a fall of 9.81m the time is 1.39s, but the system looks like not use air resistance for the delta error.

    using System.Collections;
    using System.Collections.Generic;
    using System.Threading;
    using UnityEngine;

    public class gravity_calibrator : MonoBehaviour
    {
    bool collided;
    float timer;
    float scale = 1.0f;

    void Awake()
    {
    Time.timeScale = 1.0f;
    collided = false;
    transform.position = new Vector3(0f, 9.81f * scale, 0f);
    timer = 0f;
    }


    void OnCollisionEnter(Collision collision)
    {
    if (!collided)
    {
    collided = true;
    Debug.Log("Ball fall 9.81 * " + scale.ToString() + " meters in " + timer + " seconds");
    }
    }


    void FixedUpdate()
    {
    timer += Time.fixedDeltaTime;
    }
    }
     
  8. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,149
    Please don't necropost (5 years ago with custom gravity simulation). Also, please use code-tags when posting code; the above is barely readable.

    Note that your post isn't really to do with the OP subject apart from having the word "gravity" in it.

    Please create your own thread describing your problem; in this case what you mean by "air resistance". The above is the most basic part of PhysX. Gravity is added as an impulse and linear drag tries to reduce gravity; all of which is done using numerical integration using the fixed time-step.
     
  9. Nest_g

    Nest_g

    Joined:
    Jun 18, 2019
    Posts:
    151
    After 5 years the problem is the same, the Unity inaccurate gravity simulation, is the tittle of the thread.
     
  10. MelvMay

    MelvMay

    Unity Technologies

    Joined:
    May 24, 2013
    Posts:
    11,149
    Nope, the OP isn't saying Unity is at fault nor are they discussing the gravity you're referring to which isn't the same thing; it's discussing their custom mututal gravity attraction code. Read again.
     
  11. Nest_g

    Nest_g

    Joined:
    Jun 18, 2019
    Posts:
    151
    Ok, i will be a create a new thread, thanks.
     
    MelvMay likes this.
Thread Status:
Not open for further replies.