public IEnumerator DoProcessMidAirState_Forces() { sliderLockOut = true; // Ensure that we cannot manipulate physics attributes after launch Debug.Log("Launch Cannon Ball and Observe Forces while in air"); if (failLaunch) { popup.Show(); yield break; } HideGizmoAndWidgets(); distanceGizmo.Show(); CanProcessNextStep = false; midAirStep = MidAirStep.Launching; yield return(StartCoroutine(DoLerpCameraToTransform(catapult.step3CamTransform))); float velocity = Velocity_At_Time_Of_Launch(); float ratio = ratio_Of_DEPE_Over_DGPE(); catapult.ThrowBall(catapult.launchVector.up, velocity); while (!cannonBall.paused) { yield return(null); Transform riseMarker = Utils.CreateMarker(null, 0.1f, Color.red); riseMarker.position = cannonBall.transform.position; markers.Add(riseMarker.gameObject); // Catch when the ball has left max arc height if (cannonBall.rigidBody.velocity.y < 0) { if (!cannonBall.maxHeightReached) { cannonBall.maxHeightReached = true; Transform peakMarker = Utils.CreateMarker(null, 0.2f, Color.blue); peakMarker.position = cannonBall.prevPosition; markers.Add(peakMarker.gameObject); cannonBall.PauseInAir(); yield return(StartCoroutine(DoLerpCameraToTransform(cannonBall.step4CamTransform))); } } } //yield return new WaitUntil(() => { return !camLerping; }); // wait for camera to complete lerping to Ball mid air position midAirStep = MidAirStep.Maxheight; weightPoint = cannonBall.LeftWeightPoint; resultPoint = catapult.springVector; ArrowIndicator maxHeightVelocityArrow = Instantiate(arrowBasicFrontPivotPrefab).GetComponent <ArrowIndicator>(); maxHeightVelocityArrow.SetArrowTransform(cannonBall.PeakHightVelocityMarker); maxHeightVelocityArrow.bobbing = true; maxHeightVelocityArrow.Show(); vectorArrows.Add(maxHeightVelocityArrow); maxHeightVelocityArrow.infoWidget.UpdateInfoWidget(null, (float)Math.Round(cannonBall.currentVelocity.magnitude, 2), "Velocity", true); gravArrow.SetArrowTransform(cannonBall.CenterWeightPoint); gravArrow.Show(); CanProcessNextStep = true; yield return(new WaitUntil(() => { return (midAirStep == MidAirStep.SlopeDown); })); // wait for camera to complete lerping to Ball mid air position CanProcessNextStep = false; HideGizmoAndWidgets(); // Hide all force arrows in preperation for next view step distanceGizmo.Show(); yield return(StartCoroutine(DoLerpCameraToTransform(cannonBall.step5CamTransform))); cannonBall.Resume(); // Cannonball falling downward while (!cannonBall.paused) { Transform downMarker = Utils.CreateMarker(null, 0.1f, Color.green); downMarker.position = cannonBall.transform.position; markers.Add(downMarker.gameObject); yield return(null); RaycastHit hitResult; if (RaycastFromPos(cannonBall.transform.position, -cannonBall.transform.up, Mathf.Infinity, out hitResult, true)) { float diff = cannonBall.transform.position.y - hitResult.point.y; if (diff < DistanceFromGround_At_TimeOFLaunch) { cannonBall.PauseInAir(); } } } yield return(StartCoroutine(DoLerpCameraToTransform(cannonBall.step4CamTransform))); gravArrow.SetArrowTransform(cannonBall.CenterWeightPoint); gravArrow.Show(); ArrowIndicator slopeDownVelocityArrow = Instantiate(arrowBasicBackPivotPrefab).GetComponent <ArrowIndicator>(); slopeDownVelocityArrow.bobbing = true; vectorArrows.Add(slopeDownVelocityArrow); OrientTransformToVector(ref cannonBall.ResultPoint_Centered, cannonBall.currentVelocity); slopeDownVelocityArrow.SetArrowTransform(cannonBall.ResultPoint_Centered); slopeDownVelocityArrow.Show(); slopeDownVelocityArrow.infoWidget.UpdateInfoWidget(null, (float)Math.Round(cannonBall.currentVelocity.magnitude, 2), "Velocity", true); CanProcessNextStep = true; yield return(new WaitUntil(() => { return (midAirStep == MidAirStep.CompleteArc); })); // wait for camera to complete lerping to Ball mid air position CanProcessNextStep = false; HideGizmoAndWidgets(); distanceGizmo.Show(); yield return(StartCoroutine(DoLerpCameraToTransform(cannonBall.step5CamTransform))); // RE focus camera cannonBall.Resume(); // resume cannon ball trajectory // Draw the rest of the arc markers while (!cannonBall.paused && cannonBall.inAir) { Transform downMarker = Utils.CreateMarker(null, 0.1f, Color.green); downMarker.position = cannonBall.transform.position; markers.Add(downMarker.gameObject); yield return(null); } yield return(new WaitUntil(() => { return (cannonBall.rigidBody.velocity == Vector3.zero); })); // wait for camera to complete lerping to Ball mid air position CanProcessNextStep = true; cannonBall.transform.rotation = Quaternion.identity; midAirStep = MidAirStep.Undefined; // Mid air step is over; activeCoroutine = null; }