private IEnumerator <float> MoveObjects() { canJump = false; float jumpProgress = 0f; // Frog jump animation. while (jumpProgress < 1f) { if (ProcessFrogJump(jumpProgress)) { break; // Jump ended early; frogEndPos modified. } jumpProgress += Time.deltaTime / JUMP_TIME; yield return(0f); } // Snap to jump end pos. frog.position = frogEndPos; frogMeshTrans.localRotation = Quaternion.Euler(defaultFrogTilt); frogShadow.localPosition = frogShadowOffset; // Move the camera based on frog movement. bool landedOnCoast = WithinCoastline(frog.position); if (landedOnCoast) { if (leftTheBeach) { AchievementController.instance.AwardEventAchievement(AchievementID.IPreferTheBeach, false); } if (frogEndPos.y < coastlineHeight) { frogEndPos.y = coastlineHeight; frog.position = frogEndPos; } Timing.RunCoroutine(LoseRoutine(false)); } else { // Move camera. Vector3 camMove = frogEndPos - frogStartPos; targetCamPos.x += camMove.x; targetCamPos.z += camMove.z; // Check if frog landed on pad. JumpStatus status = JumpStatus.Failed; int landedPosIndex = -1; attachedTile = GetJumpResult(out status, out landedPosIndex); if (attachedTile != null) { // Yay, the frog made it. Attach frog to this tile. attachedTile.OnFrogAttached(frog); // Achievement logic. leftTheBeach = true; if (landedPosIndex > 0) { // Landed on an offscreen tile. AchievementController.instance.AwardEventAchievement(AchievementID.SixthSense, false); } // Calculate score and play other effects. CalculateNewScore(attachedTile, status); // All insects before or equal to this tile should disappear regardless if the player hit it or not. // Also, going backwards or landing on the same tile will not award the player extra points. int targetTileDepth = attachedTile.mapDepth; foreach (TileEntity tile in tileController.activeTiles) { if (tile.mapDepth <= targetTileDepth) { tile.didAwardScore = true; bool eaten = (tile == attachedTile && (status == JumpStatus.Perfect || status == JumpStatus.NearMiss_Perfect)); tile.ClearInsect(frog.position, eaten); } } // If the nearly missed the tile, make the frog hop back on the "safe area" if (status == JumpStatus.NearMiss_Perfect || status == JumpStatus.NearMiss_Success) { yield return(Timing.WaitForSeconds(STABILIZE_JUMP_DELAY)); // Get start and end positions for stabilize jump. frogStartPos = frog.position; frogEndPos = attachedTile.GetStablePosition(frogStartPos, frogRadius, STABILIZE_JUMP_DIST_MIN, 0); curJumpDist = Mathf.Max(STABILIZE_JUMP_DIST_MIN, (frogEndPos - frog.position).magnitude); Vector3 stableDir = (frogEndPos - frog.position); stableDir.y = 0f; targetCamPos += stableDir; jumpProgress = 0f; // Rotate frog towards jump direction. UpdateFrogRotationY(stableDir.x, stableDir.z); // Frog jump animation. while (jumpProgress < 1f) { if (ProcessFrogJump(jumpProgress)) { break; } jumpProgress += Time.deltaTime / STABILIZE_JUMP_TIME; yield return(0f); } // Snap to jump end pos. frogEndPos.y = attachedTile.topSurfaceY; // Force the frog to sit on the tile's top surface. frog.position = frogEndPos; frogMeshTrans.localRotation = Quaternion.Euler(defaultFrogTilt); frogShadow.localPosition = frogShadowOffset; attachedTile.PlayBobAnimation(); // Play small land sound. sfxSource.pitch = Random.Range(1.35f, 1.45f); sfxSource.PlayOneShot(landSound, 0.35f); } // Wait briefly before returning control to player. yield return(Timing.WaitForSeconds(NEXT_JUMP_DELAY)); // Only start sinking when player has control. attachedTile.StartSinking(); canJump = true; } else { Timing.RunCoroutine(LoseRoutine(true)); } } }