TrueSyncManager.RegisterITrueSyncBehaviour() -> 60 fps to 4 fps drop


I am sorry, I don't have an easy repackaged example for this, but it happened right away and was so shocking I thought I'd report it after digging through the profiler revealed the following.

In OnSyncedStart() i ran the following code to add a TrueSyncBehaviour component dynamically to TrueSync:

var stanceMgr = tsb.gameObject.AddComponent();
stanceMgr.owner = tsb.owner;

StanceManager is just some component that handles a very simple state machine. Not too important there.

Anyways, I used the static TrueSyncManager function RegisterITrueSyncBehaviour() to register the component the same way that

public static GameObject SyncedInstantiate(GameObject prefab, TSVector position, TSQuaternion rotation)

does it. For some reason, this lead to the 'owner' variable not being initialized, so I set the new component's owner to the same value as the object adding the component.

However, in some bizzare twist, the following happened:

Performance dropped to 4 fps... and when I ran a deep profile, AbstractLockstep.ExecutePhysicsStep() was consuming 55% of the resources and Physics2DWorldManager.UpdateStep() consumed 41% of total resources.

That implies there's some sort of loop maybe? I don't know.

A deeper dig revealed this usage that ContactManager.Collide was soaking 34% on ComputeDistance? Seems strange to me.

Wish you guys the best,


  • Xelnath
    edited July 2017
    Tracked this down to being due to something called the ConstraintHierarchy2D not being properly updated - causing all of the colliders created to be anchored around the origin repeatedly and unable to move. Trying to fix now.
  • Thanks @Xelnath, it is an interesting finding, if have sucess on fixing that it will be welcome to you share here, so other devs could take advantage as well.
  • Had to hack around it really badly... this is probably not what was intended, but here's what we did:

    * @brief Property access to position.
    * It works as proxy to a Body's position when there is a collider attached.
    public TSVector2 position {
    get {
    if (tsCollider != null && tsCollider.Body != null) {
    return tsCollider.Body.TSPosition - scaledCenter;

    return _position;
    set {
    TSVector2 delta = value-_position;
    _position = value;

    // Grossly excessive, but I am not sure how how else to do this...
    if (tsCollider != null && tsCollider.Body != null)
    TSVector2 centerPos = _position + scaledCenter;
    tsCollider.Body.TSPosition = centerPos;

    var tsBody = tsCollider.Body;
    var body = tsBody as TrueSync.Physics2D.Body;
    for ( int i = 0; i < body.bodyConstraints.Count; i ++ )
    var con = body.bodyConstraints[i];
    if ( con is TrueSync.Physics2D.ConstraintHierarchy2D )
    TSVector2 parentCenter =;
    if ( tsParent != null )
    parentCenter = tsParent.position + tsParent.scaledCenter;

    TrueSync.Physics2D.ConstraintHierarchy2D ch = con as TrueSync.Physics2D.ConstraintHierarchy2D;
    var offset = ch.childOffset;
    ch.childOffset = centerPos - ch.parent.TSPosition;
  • Yeah @Xelnath, you right, it adds some complexity, but congrats to find out a solution, it will help to better understand the issue.