public override void StartKinetic(VisualPayload payload, Func <float, float> translateTime)
        {
            var startVector           = StartPosition.GetFirstValue(payload.Data);
            var endVector             = EndPosition.GetFirstValue(payload.Data);
            var startTime             = TransitionTime.GetFirstValue(payload.Data);
            var transitionTimeInverse = 1f / (TransitionDuration.GetFirstValue(payload.Data));

            var bound = payload.VisualData.Bound.CreateDependingBound("Lerp Position");

            bound.transform.parent = payload.VisualData.Bound.transform.parent;

            payload.VisualData.Bound.transform.parent = bound.transform;

            var movementSatellite =
                bound.gameObject.AddComponent <BoundMovementSatellite>();

            var newPayload = new VisualPayload(payload.Data, new VisualDescription(bound));

            movementSatellite.MovementFunc = (trans) =>
            {
                float proportion = (Time.time - startTime) * transitionTimeInverse;

                if (proportion >= 1f)
                {
                    trans.position = endVector;

                    movementSatellite.Cleanup();
                    return;
                }

                proportion = translateTime(proportion);

                trans.position = Vector3.Lerp(startVector, endVector, proportion);
            };

            movementSatellite.CleanupFunc = (trans) =>
            {
                JobManager.Instance.StartJob(
                    Finished.Transmit(newPayload), jobName: "Kinetic Finished", startImmediately: true, maxExecutionsPerFrame: 1);
            };


            // execute first step immediately to set initial position
            movementSatellite.MovementFunc(movementSatellite.transform);
        }