Phong13 / BulletSharpUnity3d

A fork of the BulletSharp project to make the Bullet Physics Engine usable from C# code in Unity3d
Other
549 stars 145 forks source link

FixedUpdate not called in every frame #49

Open fi4sk0 opened 6 years ago

fi4sk0 commented 6 years ago

Hey everybody,

first of all thanks to @Phong13 for the awesome work!

I'm having trouble with a very simple test: I created Scene with BBox and added a Component that just adds an upward force as such:

public class Float : MonoBehaviour {

    public Vector3 force;

    BRigidBody rb;

    void Start () {
        rb = GetComponent<BRigidBody>();
    }

    private void FixedUpdate()
    {
        rb.AddForce(force);
        Debug.Log("Unity: " + Time.frameCount);
        Debug.Log("bphysics: " + BPhysicsWorld.Get().frameCount);
    }
}

the force Vector is set to (0, 10, 0). Gravity in BulletPhysicsWorld is set to -9.81. The mass of the BBox is 1. I expected the box to slowly accelerate up, but it just drops to the floor.

The debug output tells me that both the Unity and the BPhysicsWorld provided frameCount do not increase by 1. Sometimes by 2, sometimes they don't increase. It is possible that I miss some frames? I'm clear on the fact that hovering this object can only work if the force is applied on every frame. As I increased the upward force, at some point there is some jerky movement of the box:

https://youtu.be/tf4bAij0SAE

Please note that the same Script works as expected staying in the Unity PhysX World.

I didn't touch the Script Execution order or anything else. I'm using Unity 2018.2.5f1 Personal and BulletUnity from the Asset Store.

Phong13 commented 6 years ago

Hi Tim,

I am working on a new version of the Bullet Unity plugin that always does exactly one Bullet Physics timestep for each Unity fixed timestep. The timing is not 100% accurate but things behave MUCH better. It is not ready for release yet, but you can replace the code in BPhysicsWorldLateUpdateHelper with the code in this thread:

`protected virtual void FixedUpdate() { if (m_ddWorld != null) { float deltaTime = UnityEngine.Time.time - m_lastSimulationStepTime; if (deltaTime > 0f) { ///stepSimulation proceeds the simulation over 'timeStep', units in preferably in seconds. ///By default, Bullet will subdivide the timestep in constant substeps of each 'fixedTimeStep'. ///in order to keep the simulation real-time, the maximum number of substeps can be clamped to 'maxSubSteps'. ///You can disable subdividing the timestep/substepping by passing maxSubSteps=0 as second argument to stepSimulation, but in that case you have to keep the timeStep constant. int numSteps = m_ddWorld.StepSimulation(m_fixedTimeStep, m_maxSubsteps, m_fixedTimeStep);

                m__frameCount += numSteps;
                //Debug.Log("FixedUpdate " + numSteps);
                m_lastSimulationStepTime = UnityEngine.Time.time;
            }
        }

        //collisions
        if (m_collisionEventHandler != null)
        {
            m_collisionEventHandler.OnPhysicsStep(m_world);
        }
    }

`