Hi,
since Unity uses box2d for the 2D environment I was wondering if it’s possible to simulate the bodies path with a second box2d engine. If it would be possible to get the bodies in both engines in sync, then one could use the additional engine as a simulation engine and execute steps manually but also have the built-in engine in use.
I downloaded Farseer from the Asset Store, set up a second physics world, copied all unity bodies into farseer and adjusted some configs.
body = BodyFactory.CreateRectangle(world,
gObj.transform.localScale.x, //width
gObj.transform.localScale.y, //height
1f, //density
new FVector2(gObj.transform.position.x, gObj.transform.position.y)); // position
//apply unity physics properties to Farseer bodies
body.Rotation = gObj.transform.rotation.eulerAngles.z * Mathf.Deg2Rad;
body.Friction = gObj.collider2D.sharedMaterial.friction;
body.Restitution = gObj.collider2D.sharedMaterial.bounciness;
if(gObj.rigidbody2D != null)
{
body.Mass = gObj.rigidbody2D.mass;
body.AngularDamping = gObj.rigidbody2D.angularDrag;
body.LinearDamping = gObj.rigidbody2D.drag;
}
The result by now is that the unity bodies and farseer bodies are in sync for about 10 seconds but losing sync then. Before they lose sync, they’re jumping around and contacting the walls multiple times all in sync.
The images are showing the unity bodies (white opaque) behind the half transparent farseer bodies (green and red). The last screenshot shows the time when the bodies lose sync.
Velocity and position iterations are 8, 3 in both engines. Fixed timestep is set to 0.0001 (the higher it is, the earlier it get out of sync).
There are a bunch of Farseer settings I didn’t touch - I hope they are all the same in Unity since most can’t be changed in Unity:
public const float MaxFloat = 3.402823466e+38f;
public const float Epsilon = 1.192092896e-07f;
public const float Pi = 3.14159265359f;
public static bool FixedUpdate = true;
public static bool EnableDiagnostics = true;
public static int VelocityIterations = 8;
public static int PositionIterations = 3;
public static bool ContinuousPhysics = true;
public static int TOIVelocityIterations = 8;
public static int TOIPositionIterations = 20;
public const int MaxSubSteps = 8;
public static bool EnableWarmstarting = true;
public static bool AllowSleep = true;
public static int MaxPolygonVertices = 8;
public static bool UseFPECollisionCategories = true;
public static Category DefaultFixtureCollisionCategories = Category.Cat1;
public static Category DefaultFixtureCollidesWith = Category.All;
public static Category DefaultFixtureIgnoreCCDWith = Category.None;
public static bool ConserveMemory = false;
public const int MaxManifoldPoints = 2;
public const float AABBExtension = 0.1f;
public const float AABBMultiplier = 2f;
public const float LinearSlop = 0.005f;
public const float AngularSlop = 0.03490659f;
public const float PolygonRadius = 0.01f;
public const int MaxTOIContacts = 32;
public const float VelocityThreshold = 1f;
public const float MaxLinearCorrection = 0.2f;
public const float MaxAngularCorrection = 0.1396264f;
public const float Baumgarte = 0.2f;
public const float TOIBaumgarte = 0.75f;
public const float TimeToSleep = 0.5f;
public const float LinearSleepTolerance = 0.01f;
public const float AngularSleepTolerance = 0.03490659f;
public const float MaxTranslation = 2f;
public const float MaxTranslationSquared = 4f;
public const float MaxRotation = 1.570796f;
public const float MaxRotationSquared = 2.467401f;


