0

I'm integrating Newton physics engine inside unity, everything works perfectly simulation wise, but I'm facing a strange error happening randomly during running.

While the simulation going on it will stop and throw an exception:

NullReferenceException: Object reference not set to an instance of an object
NewtonNet.NewtonBody.ApplyForceAndTorque (IntPtr unused, Single timestep, Int32 threadIndex) (at Assets/Plugins/NewtonNet.cs:208)
NewtonNet.NewtonWorld.Update (Single timestep) (at Assets/Plugins/NewtonNet.cs:109)
NewtonNet.NewtonWorld.Iterate (Single fps, Int32 iterations) (at Assets/Plugins/NewtonNet.cs:123)
Main.Update () (at Assets/Main.cs:146)

Newton uses a callback to apply forces and torques, and it calls it every iteration. I wrap this callback to call C# delegate function this way:

public class NewtonBody : IDisposable
{
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    delegate void ApplyForceAndTorqueCallback(IntPtr body, float timestep, int threadIndex);

    [DllImport(Common.NewtonDLL)]
    static extern void NewtonBodySetForceAndTorqueCallback(IntPtr bodyPtr, ApplyForceAndTorqueCallback callback);

    public IntPtr bodyPtr;

    public delegate void ForceAndTorqueHandler(NewtonBody sender, float timestep, int threadIndex);


    public event ForceAndTorqueHandler ForceAndTorqueCallback;

    public void ApplyForceAndTorque(IntPtr unused, float timestep, int threadIndex)
    {
        if (ForceAndTorqueCallback != null)
        {
            ForceAndTorqueCallback(this, timestep, threadIndex);
        }
    }

    public NewtonBody(IntPtr bodyPtr)
    {
        this.bodyPtr = bodyPtr;

        NewtonBodySetForceAndTorqueCallback(this.bodyPtr, ApplyForceAndTorque);
    }
}

In the main script I declare the event method like this:

void ApplyGravity(NewtonBody body, float timestep, int threadIndex)
{
    body.SetForce(new [] { 0f, -9.8f * body.Mass, 0f, 0f });
}

I kind of desperate, I tried everything but nothing works. I read around it's the GC that frees some unmanaged memory but I can't tell which??

Please help! Thanks!

Jay3D
  • 79
  • 1
  • 4
  • Not really a solution, but using reference variables without checking if they are null is the path to every kind of nasty problems. Why don't you add a simple _if(body != null)_ to your SetForce call? – Steve Jul 25 '15 at 19:15
  • The most likely problem is that the event field `ForceAndTorqueCallback` changes to `null` between the time it is checked and the time you actually try to use it. But without [a good, _minimal_, _complete_ code example](https://stackoverflow.com/help/mcve) that reliably reproduces the problem, it's not possible to state exactly why that happens, nor what the best fix is. Maybe you just need to follow the normal .NET event-raising idiom of storing the event field value in a local variable before checking and invoking it. Or maybe it's more complicated than that. There's not enough detail here. – Peter Duniho Jul 26 '15 at 05:10
  • In any case, the duplicate question provides detailed information on how to debug this exception specifically. You should only post a question once you have debugged this enough to ask for help more specific than simply describing the exception, providing an incomplete code example, and hoping someone else will fix it for you. – Peter Duniho Jul 26 '15 at 05:11
  • Thanks a lot Peter, I found the cause of the crash. The GC is collecting the delegate method because it's no longer used in managed code and only called from native code at certain intervals, so I assigned the method to a private static field to prevent the GC from collecting it, and used that field as the callback for the native function. – Jay3D Jul 26 '15 at 07:00

0 Answers0