Search Unity

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

Cant see this other as error of the physics engine

Discussion in 'Physics' started by popeye1, Feb 6, 2015.

  1. popeye1

    popeye1

    Joined:
    Dec 19, 2014
    Posts:
    28
    I was getting results I didn't like on velocities etc so I made a simple example that I found on the forum somewhere. This example shows how non exact Unity is when it comes to the gravity and that you can't rely on it to make non trivial calculations. At least not on my computer. (mcbookpro 2014)

    IEnumeratorCalculate() {

    Vector2 v1,v2;

    yield return new WaitForSeconds(1f);
    v1 = rigidbody2D.velocity;
    pos1 = rigidbody2D.position;
    yield return new WaitForSeconds(1f);

    v2 = rigidbody2D.velocity;
    pos2 = rigidbody2D.position;

    if (Mathf.Abs(v2.y) > 0.05f)
    Debug.Log ("acc" + (v2.y - v1.y) / 1f);


    }
    //Updateiscalledonceperframe
    void Update () {
    StartCoroutine (Calculate());
    }

    Outputs
    'Alternating between the number -10.00618 and -9.80991(my gravity is -9.81)
    So an error of 10e-2.

    I use a simple game object with rigidbody2d with standard settings and mass=10.
     
  2. TiG

    TiG

    Joined:
    Feb 28, 2011
    Posts:
    311
    Physics events are calculated in FixedUpdate and are out of step with Update, thus you can't get reliable results from it. You should use FixedUpdate instead.
     
  3. popeye1

    popeye1

    Joined:
    Dec 19, 2014
    Posts:
    28
    Thanks for the advice. Tried it still having same unreliable results :(

    void FixedUpdate(){
    StartCoroutine (Calculate());


    }
     
  4. MatthewW

    MatthewW

    Joined:
    Nov 30, 2006
    Posts:
    1,356
    You're misunderstanding FixedUpdate.

    Look at the chart here:
    http://docs.unity3d.com/Manual/ExecutionOrder.html



    Your coroutine is just waiting a second and looking at values before or after.

    What is your physics timestep set to? The Unity default is 50Hz, which is actually pretty low. If you care about deep accuracy, increase this to 120Hz or even 240Hz.

    Only apply forces in FixedUpdate. If you're yielding in a coroutine, this means yield return new WaitForFixedUpdate().

    Your actual trajectory will vary depending on the physics timestep (imagine drawing more and more segments on a parabolic curve--low timesteps mean it will be quite segmented). This article on trajectories has some guidance there: http://www.iforce2d.net/b2dtut/projected-trajectory
     
    popeye1 likes this.
  5. TiG

    TiG

    Joined:
    Feb 28, 2011
    Posts:
    311
    Oh I didn't read your code. "yield return new WaitForSeconds(1f)" ruins everything. You can do the calculations in each cycle of FixedUpdate and maybe later average them. Also physics 2D is rather new and may be a bit buggy, I don't have much experience with 2d.
     
  6. popeye1

    popeye1

    Joined:
    Dec 19, 2014
    Posts:
    28
    Thanks Matthew ,the link was perfect.

    Though, I thought that I couldn't rely on timestep for fixed update as well but works perfect .
    Now gravity jus have negligible fluctuations.
    Thanks all!