[BUG] body.FixtureList can be null but OnDisable() doesn't handle that scenario



NullReferenceException: Object reference not set to an instance of an object
at TrueSync.Physics2D.Body.set_Enabled (Boolean value) [0x0009e] in Z:\Projects\Atomech\project-sidescroller\Assets\Standard Assets\TrueSync\Physics\Farseer\Dynamics\Body.cs:420
at TrueSync.TSCollider2D.OnDisable () [0x00014] in Z:\Projects\Atomech\project-sidescroller\Assets\Standard Assets\TrueSync\Unity\TSCollider2D.cs:307
UnityEngine.Object:Destroy(Object, Single)
UnityEngine.Object:Destroy(Object) (at C:\buildslave\unity\build\artifacts\generated\common\runtime\UnityEngineObjectBindings.gen.cs:83)
TrueSync.Physics2DWorldManager:OnRemovedRigidBody(Body) (at Z:\Projects\Atomech\project-sidescroller\Assets\Standard Assets\TrueSync\Unity\Physics2DWorldManager.cs:136)
TrueSync.Physics2D.World:ProcessRemovedBodies() (at Z:\Projects\Atomech\project-sidescroller\Assets\Standard Assets\TrueSync\Physics\Farseer\Dynamics\World.cs:383)
TrueSync.Physics2D.WorldClone2D:Restore(IWorld) (at Z:\Projects\Atomech\project-sidescroller\Assets\Standard Assets\TrueSync\Physics\Farseer\Extra\Clones\WorldClone2D.cs:176)
TrueSync.RollbackLockstep:RestorePreviousState()
TrueSync.RollbackLockstep:Rollback(Int32, Int32)
TrueSync.RollbackLockstep:BeforeStepUpdate(Int32, Int32)
TrueSync.AbstractLockstep:Update()
TrueSync.TrueSyncManager:FixedUpdate() (at Z:\Projects\Atomech\project-sidescroller\Assets\Standard Assets\TrueSync\Unity\TrueSyncManager.cs:724)
Culprit code is here:

public bool Enabled
{
set
{
if (value == _enabled)
return;

if (value)
{
// Create all proxies.
IBroadPhase broadPhase = _world.ContactManager.BroadPhase;
for (int i = 0; i < FixtureList.Count; i++)
{
FixtureList[i].CreateProxies(broadPhase, ref _xf);
}

// Contacts are created the next time step.
}
else
{
// Destroy all proxies.
IBroadPhase broadPhase = _world.ContactManager.BroadPhase;

for (int i = 0; i < FixtureList.Count; i++)
{
FixtureList[i].DestroyProxies(broadPhase);
}

// Destroy the attached contacts.
ContactEdge ce = ContactList;
while (ce != null)
{
ContactEdge ce0 = ce;
ce = ce.Next;
_world.ContactManager.Destroy(ce0.Contact);
}
ContactList = null;
}

_enabled = value;
}
get { return _enabled; }
}
As you can see, the FixtureList is not checked for a non-null value.

FixtureList can be made null by at least one place in
public void ProcessRemovedBodies() of World.cs

Comments