Search Unity

[HELP] Gravity Bug?

Discussion in 'Physics' started by watah, Feb 11, 2016.

  1. watah

    watah

    Joined:
    Feb 11, 2016
    Posts:
    3
    Summary:

    I was able to achieve a perfect bouncing ball using an initial velocity of 0, but when I give it a non-zero initial velocity or apply any force, the ball keeps gaining height.

    Baseline:

    * Create a ball with a Rigidbody2D with no Auto Mass, Mass 1, Linear Drag 0, Angular Drag 0.05, Gravity Scale 1, not Kinematic, no Interpolate, Start Awake, Continuous Collision Detection, no constraints.

    * Add a Circle Collider 2D to the ball with a material with 1 bounciness, 0 friction, not trigger, no effector.

    * Create a floor with a Box Collider 2D with default material, is trigger, no effector.

    * Attach a script to the ball so that when you press spacebar it sets it's transform.position to be somewhere above the floor and it's GetComponent<Rigidbody2D>().velocity = new Vector2(0f, 0f);

    * The ball will bounce perfectly to its original height each time.

    How to break it:

    * Change the value in bold above to 1f.

    Expected behavior:

    * I would expect the ball to go up a little at first and then keep bouncing to that new height over and over again.

    Observed behavior:

    * The balls does go up a little at first, but then it goes up higher and higher and higher with each bounce.

    Things I tried:

    * Setting velocity to 0f, but then using AddForce(new Vector2(0f, 1f),ForceMode2D.Impulse) to cause the upward motion. -- This produces the same deviation from expected behavior as above.

    * Setting the velocity (or adding force) inside a FixedUpdate() call instead of an Update() call. -- This produces the same deviation from expected behavior as above.
     
  2. watah

    watah

    Joined:
    Feb 11, 2016
    Posts:
    3
    Here's a link that shows the problem. (Link expires on March 13th, 2016.)
    http://gamebucket.io/game/7817e417-baa5-4e8b-9d54-10457d010770

    Also, side question: in the case where it starts at rest, why doesn't the total energy remain constant?

    If I remember my physics right, energy is neither created nor destroyed, so potential energy plus kinetic energy should remain constant.
     
  3. watah

    watah

    Joined:
    Feb 11, 2016
    Posts:
    3
    I created an enhanced version of the demo app you can use here: http://gamebucket.io/game/790591d2-67bc-4a62-acce-097852291fbe

    It compares the unity 2D physics engine result (the grey ball) with the expected result (the blue ball).

    It appears there are actually two problems here, though the second may be related to the first.

    First Problem

    This problem shows up when the initial velocity of the ball is 0. In the unity 2D physics engine, the ball alternates between bouncing to a height of 4 and bouncing to a height of 3.92.

    The problem seems to be the way in which the unity 2D physics engine calculates the new position of an object under gravity. It appears that the unity 2D physics engine currently does this:
    • NewVelocity = OldVelocity + Gravity*DeltaTime
    • NewPosition = OldPosition + NewVelocity*DeltaTime
    However, the correct equation for NewPosition should be
    • NewPosition = OldPosition + OldVelocity*DeltaTime + (1/2)*Gravity*(DeltaTime^2)
    or, alternatively,
    • NewPosition = OldPosition + NewVelocity*DeltaTime - (1/2)*Gravity*(DeltaTime^2)
    Since DeltaTime is usually constant, (1/2)*Gravity*(DeltaTime^2) is usually also constant, and small, but it is a factor that should be taken into account, so that the ball always bounces to height 4 instead of alternating between bouncing to height 4 and height 3.92.

    If you open the enhanced demo app and click "step" you will see that the unity 2d physics engine calculates the correct velocity on each step on the way down but gets the position wrong. If you speed it up and click "go", you can watch it bounce to alternating heights.

    Second Problem
    The second problem shows up when the initial velocity of the ball is 1. In the unity 2D physics engine, the ball gradually bounces higher and higher and higher.

    I still do not know what causes this problem, as I do not have the code for the unity 2D physics engine. (If this is available somewhere, let me know, and I can give it a look.)

    You can see the effect in the demo app by clicking the "vel=1" button and then clicking "go".

    Other Benefits
    Fixing these problems will also fix the total energy calculations. You will see that the total energy in the expected result remains constant regardless of the simulation. However, the unity 2d physics engine result lets the total energy fluctuate up and down for 0 initial velocity and lets the total energy grow unbounded for 1 initial velocity.