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); }