public override bool Join(AttachObject obj)
        {
            FlexibleTransitionerState state = (FlexibleTransitionerState)obj.transitionerState;

            if (state.detachedSnapshot == null)
            {
                state.detachedSnapshot = Snapshot.TakeSnapshot(onDetachOptions, obj.attachable, obj.spriteRenderer);
            }

            // convert our attach settings to snapshot-friendly restore options, and put our data in the snapshot
            state.attachedSnapshot = new Snapshot(obj.attachable, obj.spriteRenderer);
            state.attachedSnapshot.options.rigidbodyBehavior = (RigidbodyRestoreBehavior)
                                                               onAttachOptions.rigidbodyBehavior;

            state.attachedSnapshot.options.restorePosition = onAttachOptions.positionOptions.behavior
                                                             != PositionBehavior.DoNothing;
            state.attachedSnapshot.options.tweenPositionOptions = onAttachOptions.positionOptions.tweenOptions;
            state.attachedSnapshot.options.moveMethod           = onAttachOptions.positionOptions.moveMethod;

            state.attachedSnapshot.options.restoreRotation = onAttachOptions.rotationOptions.behavior
                                                             != RotationBehavior.DoNothing;
            state.attachedSnapshot.options.tweenRotationOptions = onAttachOptions.rotationOptions.tweenOptions;
            state.attachedSnapshot.options.rotateMethod         = onAttachOptions.rotationOptions.rotateMethod;

            state.attachedSnapshot.options.restoreSortingOrder = onAttachOptions.adoptSortingOrderOptions.enabled;
            if (state.attachedSnapshot.options.restoreSortingOrder && obj.spriteRenderer)
            {
                state.attachedSnapshot.data.sortingOrder = obj.spriteRenderer.sortingOrder;
            }
            // todo - sorting layer?

            state.attachedSnapshot.options.restoreFlipX = onAttachOptions.adoptFlipXOptions.enabled;
            if (state.attachedSnapshot.options.restoreFlipX && obj.spriteRenderer)
            {
                state.attachedSnapshot.data.flipX = onAttachOptions.adoptFlipXOptions.param.GetFlipX(
                    obj.attachment, obj);
            }


            state.attachedSnapshot.options.restoreFlipY = onAttachOptions.adoptFlipXOptions.enabled;
            if (state.attachedSnapshot.options.restoreFlipY && obj.spriteRenderer)
            {
                state.attachedSnapshot.data.flipY = onAttachOptions.adoptFlipXOptions.param.GetFlipY(
                    obj.attachment, obj);
            }

            // state.attachedSnapshot.options.restoreLayer = onAttachOptions.adoptLayerOptions.enabled;
            // if (state.attachedSnapshot.options.restoreLayer) {
            //     ParamSelector selector = onAttachOptions.adoptLayerOptions.param;
            //     AttachObject provider = obj.ResolveProvider(selector);
            //     if (provider != null)
            //         state.attachedSnapshot.data.layer = obj.GetLayer(selector.name, selector.defaultParam);
            // }

            state.attachedSnapshot.Apply(
                GetDestinationPosition: () => { return(GetDesiredPositionForObject(obj)); },
                GetDestinationRotation: () => { return(GetDesiredRotationForObject(obj)); },
                SnapshotComplete: () => {
                state.attachedSnapshot = null;
                obj.SetJoined();
            }, tweenFirst: false);     // fixme - make tweenFirst optional

            return(false);
        }